Merge branch 'issue-77-card-height' into issue-77
This commit is contained in:
commit
7a1c4d3dbe
81 changed files with 1439 additions and 683 deletions
28
.env.example
28
.env.example
|
|
@ -3,7 +3,6 @@ APP_ENV=local
|
|||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
ASSET_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
|
|
@ -38,26 +37,6 @@ MAIL_ENCRYPTION=null
|
|||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Sentry
|
||||
SENTRY_LARAVEL_DSN=
|
||||
|
||||
|
|
@ -82,3 +61,10 @@ LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=""
|
|||
MESBR_REF_SITE=
|
||||
MESBR_REF_CAMP=
|
||||
MESBR_ENDPOINT=
|
||||
|
||||
# SAML
|
||||
SAML2_DEFAULT_TENANT_UUID=
|
||||
SAML2_SP_CERT_x509=
|
||||
SAML2_SP_CERT_PRIVATEKEY=
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL=
|
||||
SAML2_CONTACT_SUPPORT_EMAIL=
|
||||
|
|
|
|||
|
|
@ -24,13 +24,11 @@ class FetchDigitalRecruiterOffersCommand extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
(new FetchDigitalRecruiterOffers())->handle();
|
||||
$this->info('Offers fetch 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
app/Console/Commands/FetchMesBrCommand.php
Normal file
34
app/Console/Commands/FetchMesBrCommand.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\FetchMesBr;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class FetchMesBrCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:mesbr';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fetch mesbr discounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
(new FetchMesBr())->handle();
|
||||
$this->info('Discounts fetch 👌');
|
||||
}
|
||||
}
|
||||
|
|
@ -26,10 +26,11 @@ class TestMail extends Command
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||
});
|
||||
$this->info('Mail send 👌');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,13 +47,6 @@ class UserCreate extends Command
|
|||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
|
|
@ -64,9 +57,9 @@ class UserCreate extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): int
|
||||
public function handle(): void
|
||||
{
|
||||
$this->first_name = null;
|
||||
$this->addFirstName();
|
||||
|
|
@ -77,9 +70,6 @@ class UserCreate extends Command
|
|||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$this->role = null;
|
||||
$this->addRole();
|
||||
|
||||
|
|
@ -87,7 +77,6 @@ class UserCreate extends Command
|
|||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
|
|
@ -95,8 +84,6 @@ class UserCreate extends Command
|
|||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -174,22 +161,6 @@ class UserCreate extends Command
|
|||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
|
|
@ -199,7 +170,7 @@ class UserCreate extends Command
|
|||
{
|
||||
while (is_null($this->role)) {
|
||||
try {
|
||||
$tmp = $this->choice(
|
||||
$tmp = $this->choice(
|
||||
'Select his role',
|
||||
[
|
||||
Str::ucFirst(RoleEnum::conceptor->label()),
|
||||
|
|
@ -207,8 +178,6 @@ class UserCreate extends Command
|
|||
Str::ucFirst(RoleEnum::visitor->label())
|
||||
],
|
||||
Str::ucFirst(RoleEnum::visitor->label()),
|
||||
$maxAttempts = null,
|
||||
$allowMultipleSelections = false
|
||||
);
|
||||
if ($tmp === Str::ucFirst(RoleEnum::conceptor->label())) {
|
||||
$tmp = RoleEnum::conceptor;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@ class HomeController extends Controller
|
|||
$discountsTotal = $discountModels->sum('value');
|
||||
return (auth('club')->check())
|
||||
? view('club.pages.home.homepage', compact('newsClubModels', 'discountModels', 'discountsTotal'))
|
||||
: view('club.pages.home.guest', compact('newsClubModels'));
|
||||
: view('club.pages.home.guest', compact('newsClubModels', 'discountsTotal'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ class Kernel extends HttpKernel
|
|||
\App\Http\Middleware\SecureHeaders::class
|
||||
],
|
||||
|
||||
'saml' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:40,1',
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use App\Models\User;
|
|||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -44,14 +43,6 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
|
|
@ -68,7 +59,6 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Requests\Bo\Users;
|
|||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
|
|
@ -32,11 +31,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
$this->merge([
|
||||
'published' => $authUserModel->getKey() !== $userModel->getKey() ?
|
||||
$this->boolean('published') :
|
||||
true,
|
||||
'password' => $this->input('password') ??
|
||||
\optional($this->route('user'))->password,
|
||||
'password_confirmation' => $this->input('password_confirmation') ??
|
||||
\optional($this->route('user'))->password
|
||||
true
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -52,15 +47,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')->ignore(\optional($this->route('user'))->getRouteKey())
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class StaticPage extends Model
|
|||
});
|
||||
static::updating(function (self $model) {
|
||||
self::assertTitleIsUnique($model->seo_title, $model->getKey());
|
||||
$model->slug = Str::slug($model->seo_title);
|
||||
$model->slug = Str::slug($model->seo_title ?? $model->title ?? str()->random(20));
|
||||
if (!is_null($model->picture)) {
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
|
@ -123,8 +123,10 @@ class StaticPage extends Model
|
|||
*/
|
||||
private static function assertTitleIsUnique(string|null $seo_title, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'seo_title', $seo_title, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($seo_title), $id);
|
||||
if (!is_null($seo_title)) {
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'seo_title', $seo_title, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($seo_title), $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ use Illuminate\Auth\Access\AuthorizationException;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* @property string $first_name Firstname.
|
||||
* @property string $last_name Lastname.
|
||||
* @property string $email Email.
|
||||
* @property string $password Password.
|
||||
* @property string $remember_token Remember_token.
|
||||
* @property \App\Enums\Users\RoleEnum $role Role.
|
||||
* @property \Illuminate\Support\Carbon $last_connection Last_connection.
|
||||
* @property \Illuminate\Support\Carbon $published Published status.
|
||||
* @property \Illuminate\Support\Carbon $published_at Publication status update date.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
|
|
@ -38,7 +38,6 @@ class User extends Authenticatable
|
|||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
'published',
|
||||
'published_at',
|
||||
|
|
@ -50,7 +49,6 @@ class User extends Authenticatable
|
|||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
|
|
@ -61,7 +59,7 @@ class User extends Authenticatable
|
|||
*/
|
||||
protected $casts = [
|
||||
'role' => RoleEnum::class,
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_connection' => 'date',
|
||||
'published' => 'boolean',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
|
|
@ -74,7 +72,6 @@ class User extends Authenticatable
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() > $model->role->value(),
|
||||
|
|
@ -82,7 +79,6 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
if (optional(auth('backend')->user())->getKey() === $model->getKey()) {
|
||||
\validator(
|
||||
['published' => $model->published],
|
||||
|
|
@ -97,19 +93,4 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Update password.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function updatePassword(self $model): void
|
||||
{
|
||||
if (Hash::needsRehash($model->password)) {
|
||||
$model->password = Hash::make($model->password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ use Illuminate\Auth\Events\PasswordReset;
|
|||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Slides\Saml2\Events\SignedIn;
|
||||
use Slides\Saml2\Events\SignedOut;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -38,4 +45,49 @@ class EventServiceProvider extends ServiceProvider
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Event::listen('Slides\Saml2\Events\SignedIn', function (SignedIn $event) {
|
||||
|
||||
$messageId = $event->getAuth()->getLastMessageId();
|
||||
|
||||
$fromCache = Cache::get(config('cache.prefix') . "_saml_message_id_" . $messageId);
|
||||
if ($fromCache) {
|
||||
logger()->error(
|
||||
'SAML MESSAGE ID HANDLER',
|
||||
['error' => 'Message ID : ' . $messageId . " replayed !"]
|
||||
);
|
||||
abort(403);
|
||||
} else {
|
||||
Cache::put(config('cache.prefix') . "_saml_message_id_" . $messageId, $messageId, 28800);
|
||||
// Cache for 8h.
|
||||
}
|
||||
|
||||
$user = $event->getSaml2User();
|
||||
$email = $user->getNameId();
|
||||
|
||||
$lUser = User::where('email', '=', $email)->first();
|
||||
|
||||
if (!$lUser) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
Auth::guard('backend')->login($lUser);
|
||||
session(['sessionIndex' => $user->getSessionIndex()]);
|
||||
$lUser->last_connection = now();
|
||||
$lUser->saveQuietly();
|
||||
});
|
||||
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
Event::listen('Slides\Saml2\Events\SignedOut', function (SignedOut $event) {
|
||||
Auth::guard('backend')->logout();
|
||||
Session::save();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class ViewServiceProvider extends ServiceProvider
|
|||
|
||||
Blade::directive('money', function (string $amountVariable) {
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
return "<?php echo e(app('phpMoneyFormatter')->format(new Money({$amountVariable}, app('phpMoneyCurrency')))); ?>";
|
||||
return "<?php echo e(app('phpMoneyFormatter')->format(new Money({$amountVariable} * 100, app('phpMoneyCurrency')))); ?>";
|
||||
});
|
||||
|
||||
// * Inject menuNodeList
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "uwil/le-gaulois",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"type": "project",
|
||||
"description": "Le Gaulois project.",
|
||||
"support": {
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
"require": {
|
||||
"php": "^8.3",
|
||||
"ext-bcmath": "*",
|
||||
"24slides/laravel-saml2": "^2.4",
|
||||
"axlon/laravel-postal-code-validation": "^3.7",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"diglactic/laravel-breadcrumbs": "^9.0",
|
||||
|
|
|
|||
183
composer.lock
generated
183
composer.lock
generated
|
|
@ -4,8 +4,83 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "db80cce9d97851f47e3720647bcf6138",
|
||||
"content-hash": "d9d5353325cde56c23904770ba015a27",
|
||||
"packages": [
|
||||
{
|
||||
"name": "24slides/laravel-saml2",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/24Slides/laravel-saml2.git",
|
||||
"reference": "85dadba29a54f624c29d06b9a2ba0f00186cf665"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/24Slides/laravel-saml2/zipball/85dadba29a54f624c29d06b9a2ba0f00186cf665",
|
||||
"reference": "85dadba29a54f624c29d06b9a2ba0f00186cf665",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"illuminate/console": "~5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/database": "~5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/support": "~5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"onelogin/php-saml": "^3.0|^4.0",
|
||||
"php": ">=7.1",
|
||||
"ramsey/uuid": "^3.8|^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.9",
|
||||
"phpunit/phpunit": "^7.5|^9.0",
|
||||
"squizlabs/php_codesniffer": "^2.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Saml2": "Slides\\Saml2\\Facades\\Auth"
|
||||
},
|
||||
"providers": [
|
||||
"Slides\\Saml2\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-aliases": {
|
||||
"dev-master": "2.0.8-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Slides\\Saml2\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Artem Brezhnev",
|
||||
"email": "brezzhnev@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "SAML2 Service Provider integration to your Laravel 5.4+ application, based on OneLogin toolkit",
|
||||
"homepage": "https://github.com/24slides/laravel-saml2",
|
||||
"keywords": [
|
||||
"SAML2",
|
||||
"SSO",
|
||||
"laravel",
|
||||
"onelogin",
|
||||
"saml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/24Slides/laravel-saml2/issues",
|
||||
"source": "https://github.com/24Slides/laravel-saml2/tree/2.4.0"
|
||||
},
|
||||
"time": "2024-04-13T12:57:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "axlon/laravel-postal-code-validation",
|
||||
"version": "v3.7.0",
|
||||
|
|
@ -3700,6 +3775,70 @@
|
|||
],
|
||||
"time": "2024-09-09T07:06:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "onelogin/php-saml",
|
||||
"version": "4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SAML-Toolkits/php-saml.git",
|
||||
"reference": "d3b5172f137db2f412239432d77253ceaaa1e939"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SAML-Toolkits/php-saml/zipball/d3b5172f137db2f412239432d77253ceaaa1e939",
|
||||
"reference": "d3b5172f137db2f412239432d77253ceaaa1e939",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"robrichards/xmlseclibs": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"pdepend/pdepend": "^2.8.0",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"phploc/phploc": "^4.0 || ^5.0 || ^6.0 || ^7.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"sebastian/phpcpd": "^4.0 || ^5.0 || ^6.0 ",
|
||||
"squizlabs/php_codesniffer": "^3.5.8"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "Install curl lib to be able to use the IdPMetadataParser for parsing remote XMLs",
|
||||
"ext-dom": "Install xml lib",
|
||||
"ext-openssl": "Install openssl lib in order to handle with x509 certs (require to support sign and encryption)",
|
||||
"ext-zlib": "Install zlib"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OneLogin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHP SAML Toolkit",
|
||||
"homepage": "https://github.com/SAML-Toolkits/php-saml",
|
||||
"keywords": [
|
||||
"Federation",
|
||||
"SAML2",
|
||||
"SSO",
|
||||
"identity",
|
||||
"saml"
|
||||
],
|
||||
"support": {
|
||||
"email": "sixto.martin.garcia@gmail.com",
|
||||
"issues": "https://github.com/onelogin/SAML-Toolkits/issues",
|
||||
"source": "https://github.com/onelogin/SAML-Toolkits/"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/SAML-Toolkits",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-30T15:10:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v9.99.100",
|
||||
|
|
@ -4845,6 +4984,48 @@
|
|||
},
|
||||
"time": "2024-04-13T09:45:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robrichards/xmlseclibs.git",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"php": ">= 5.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RobRichards\\XMLSecLibs\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "A PHP library for XML Security",
|
||||
"homepage": "https://github.com/robrichards/xmlseclibs",
|
||||
"keywords": [
|
||||
"security",
|
||||
"signature",
|
||||
"xml",
|
||||
"xmldsig"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robrichards/xmlseclibs/issues",
|
||||
"source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1"
|
||||
},
|
||||
"time": "2020-09-05T13:00:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "4.9.0",
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ return [
|
|||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
|
||||
'asset_url' => env('ASSET_URL'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Timezone
|
||||
|
|
|
|||
397
config/saml2.php
Normal file
397
config/saml2.php
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Tenant Model
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This will allow you to override the tenant model with your own.
|
||||
|
|
||||
*/
|
||||
|
||||
'tenantModel' => \Slides\Saml2\Models\Tenant::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Use built-in routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If "useRoutes" set to true, the package defines five new routes:
|
||||
|
|
||||
| Method | URI | Name
|
||||
| -------|---------------------------------|------------------
|
||||
| POST | {routesPrefix}/{uuid}/acs | saml.acs
|
||||
| GET | {routesPrefix}/{uuid}/login | saml.login
|
||||
| GET | {routesPrefix}/{uuid}/logout | saml.logout
|
||||
| GET | {routesPrefix}/{uuid}/metadata | saml.metadata
|
||||
| GET | {routesPrefix}/{uuid}/sls | saml.sls
|
||||
|
|
||||
*/
|
||||
|
||||
'useRoutes' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Built-in routes prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define the prefix for built-in routes.
|
||||
|
|
||||
*/
|
||||
|
||||
'routesPrefix' => '/saml2',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Middle groups to use for the SAML routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Note, Laravel 5.2 requires a group which includes StartSession
|
||||
|
|
||||
*/
|
||||
|
||||
'routesMiddleware' => ['saml'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Signature validation
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Set to true if you want to use parameters from $_SERVER to validate the signature.
|
||||
|
|
||||
*/
|
||||
|
||||
'retrieveParametersFromServer' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after successful login.
|
||||
|
|
||||
*/
|
||||
|
||||
'loginRoute' => '/bo',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after successful logout.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutRoute' => '/bo',
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login error redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after login failing.
|
||||
|
|
||||
*/
|
||||
|
||||
'errorRoute' => '/bo/login-error',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Strict mode.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If 'strict' is True, then the PHP Toolkit will reject unsigned
|
||||
| or unencrypted messages if it expects them signed or encrypted
|
||||
| Also will reject the messages if not strictly follow the SAML
|
||||
| standard: Destination, NameId, Conditions... are validated too.
|
||||
|
|
||||
*/
|
||||
|
||||
'strict' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Debug mode.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When enabled, errors must be printed.
|
||||
|
|
||||
*/
|
||||
|
||||
'debug' => env('SAML2_DEBUG', env('APP_DEBUG', false)),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Whether to use `X-Forwarded-*` headers to determine port/domain/protocol.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If 'proxyVars' is True, then the Saml lib will trust proxy headers
|
||||
| e.g X-Forwarded-Proto / HTTP_X_FORWARDED_PROTO. This is useful if
|
||||
| your application is running behind a load balancer which terminates SSL.
|
||||
|
|
||||
*/
|
||||
|
||||
'proxyVars' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Service Provider configuration.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| General setting of the service provider.
|
||||
|
|
||||
*/
|
||||
|
||||
'sp' => [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| NameID format.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specifies constraints on the name identifier to be used to
|
||||
| represent the requested subject.
|
||||
|
|
||||
*/
|
||||
|
||||
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SP Certificates.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Usually x509cert and privateKey of the SP are provided by files placed at
|
||||
| the certs folder. But we can also provide them with the following parameters.
|
||||
|
|
||||
*/
|
||||
|
||||
'x509cert' => env('SAML2_SP_CERT_x509', ''),
|
||||
'privateKey' => env('SAML2_SP_CERT_PRIVATEKEY', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Identifier (URI) of the SP entity.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Leave blank to use the 'saml.metadata' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'entityId' => env('SAML2_SP_ENTITYID', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| The Assertion Consumer Service (ACS) URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| URL Location where the <Response> from the IdP will be returned, using HTTP-POST binding.
|
||||
| Leave blank to use the 'saml.acs' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'assertionConsumerService' => [
|
||||
'url' => '',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| The Single Logout Service URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specifies info about where and how the <Logout Response> message MUST be
|
||||
| returned to the requester, in this case our SP.
|
||||
|
|
||||
| URL Location where the <Response> from the IdP will be returned, using HTTP-Redirect binding.
|
||||
| Leave blank to use the 'saml.sls' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'singleLogoutService' => [
|
||||
'url' => ''
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| OneLogin security settings.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
|
|
||||
|
|
||||
*/
|
||||
|
||||
'security' => [
|
||||
|
||||
'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
||||
'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| NameId encryption
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
|
||||
| will be encrypted.
|
||||
|
|
||||
*/
|
||||
|
||||
'nameIdEncrypted' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| AuthnRequest signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:AuthnRequest> messages sent by
|
||||
| this SP will be signed. The Metadata of the SP will offer this info
|
||||
|
|
||||
*/
|
||||
|
||||
'authnRequestsSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout request signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:logoutRequest> messages sent by this SP
|
||||
| will be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutRequestSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout response signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:logoutResponse> messages sent by this SP
|
||||
| will be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutResponseSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Whether need to sign metadata.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The possible values:
|
||||
| - false
|
||||
| - true (use certs)
|
||||
| - array:
|
||||
| ```
|
||||
| [
|
||||
| 'keyFileName' => 'metadata.key',
|
||||
| 'certFileName' => 'metadata.crt'
|
||||
| ]
|
||||
| ```
|
||||
|
|
||||
*/
|
||||
|
||||
'signMetadata' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to sign messages.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest> and
|
||||
| <samlp:LogoutResponse> elements received by this SP to be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantMessagesSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to sign assertion elements.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the <saml:Assertion> elements received by
|
||||
| this SP to be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantAssertionsSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to encrypt NameID.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the NameID received by this SP to be encrypted.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantNameIdEncrypted' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication context.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Set to false and no AuthContext will be sent in the AuthNRequest,
|
||||
|
|
||||
| Set true or don't present this parameter and you will get an
|
||||
| AuthContext 'exact' 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'
|
||||
|
|
||||
| Set an array with the possible auth context values:
|
||||
| ['urn:oasis:names:tc:SAML:2.0:ac:classes:Password', 'urn:oasis:names:tc:SAML:2.0:ac:classes:X509']
|
||||
|
|
||||
*/
|
||||
|
||||
'requestedAuthnContext' => true,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Contact information.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| It is recommended to supply a technical and support contacts.
|
||||
|
|
||||
*/
|
||||
|
||||
'contactPerson' => [
|
||||
'technical' => [
|
||||
'givenName' => env('SAML2_CONTACT_TECHNICAL_NAME', env('APP_NAME', 'Technical')),
|
||||
'emailAddress' => env('SAML2_CONTACT_TECHNICAL_EMAIL', 'no@reply.com')
|
||||
],
|
||||
'support' => [
|
||||
'givenName' => env('SAML2_CONTACT_SUPPORT_NAME', env('APP_NAME', 'Support')),
|
||||
'emailAddress' => env('SAML2_CONTACT_SUPPORT_EMAIL', 'no@reply.com')
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Organization information.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The info in en_US lang is recommended, add more if required.
|
||||
|
|
||||
*/
|
||||
|
||||
'organization' => [
|
||||
'en-US' => [
|
||||
'name' => env('SAML2_ORGANIZATION_NAME', env('APP_NAME', 'Name')),
|
||||
'displayname' => env('SAML2_ORGANIZATION_NAME', env('APP_NAME', 'Name')),
|
||||
'url' => env('SAML2_ORGANIZATION_URL', env('APP_URL', 'http://url'))
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Default tenant UUID
|
||||
*/
|
||||
|
||||
'default_tenant_uuid' => env('SAML2_DEFAULT_TENANT_UUID', null)
|
||||
|
||||
];
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?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('users', function (Blueprint $table) {
|
||||
$table->dropColumn('email_verified_at');
|
||||
$table->dropColumn('password');
|
||||
$table->date('last_connection')->nullable()->after('role');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->timestamp('email_verified_at')->nullable()->after('email');
|
||||
$table->string('password')->after('email_verified_at');
|
||||
$table->dropColumn('last_connection');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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('customers', function (Blueprint $table) {
|
||||
$table->string('hashcode')->after('email')->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->string('email')->after('hashcode')->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?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('recipes', function (Blueprint $table) {
|
||||
$table->string('tips', 500)->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('recipes', function (Blueprint $table) {
|
||||
$table->string('tips', 500)->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
107
manifest.yaml
107
manifest.yaml
|
|
@ -7,7 +7,7 @@ data:
|
|||
APP_ENV: "${APP_APP_ENV}"
|
||||
APP_KEY: "${APP_APP_KEY}"
|
||||
APP_DEBUG: "${APP_APP_DEBUG}"
|
||||
APP_URL: "https://${REDIRECT}${APP_DOMAIN}"
|
||||
APP_URL: "https://${APP_DOMAIN}"
|
||||
LOG_CHANNEL: "k8s"
|
||||
DB_HOST: "mariadb.common-services"
|
||||
DB_DATABASE: "${APP_DB_DATABASE}"
|
||||
|
|
@ -31,6 +31,11 @@ data:
|
|||
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
|
||||
DIGITAL_RECRUITER_URL: "${APP_DIGITAL_RECRUITER_URL}"
|
||||
LDC_WEB_API_KEY: "${APP_LDC_WEB_API_KEY}"
|
||||
SAML2_SP_CERT_x509: "${APP_SAML2_SP_CERT_x509}"
|
||||
SAML2_SP_CERT_PRIVATEKEY: "${APP_SAML2_SP_CERT_PRIVATEKEY}"
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL: "${APP_SAML2_CONTACT_TECHNICAL_EMAIL}"
|
||||
SAML2_CONTACT_SUPPORT_EMAIL: "${APP_SAML2_CONTACT_SUPPORT_EMAIL}"
|
||||
SAML2_DEFAULT_TENANT_UUID: "${APP_SAML2_DEFAULT_TENANT_UUID}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
@ -40,7 +45,7 @@ metadata:
|
|||
spec:
|
||||
storageClassName: "csi-cinder-classic"
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: $APP_PVC_SIZE
|
||||
|
|
@ -61,25 +66,25 @@ spec:
|
|||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
spec:
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-container
|
||||
image: $IMAGE_TAG
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-container
|
||||
image: $IMAGE_TAG
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
- name: docker-registry-credentials
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
fsGroup: 33
|
||||
fsGroupChangePolicy: "OnRootMismatch"
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
@ -90,8 +95,8 @@ spec:
|
|||
selector:
|
||||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 443
|
||||
- port: 80
|
||||
targetPort: 443
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
|
|
@ -100,16 +105,14 @@ metadata:
|
|||
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
- websecure
|
||||
- web
|
||||
- websecure
|
||||
routes:
|
||||
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: redirect-no-www-to-www
|
||||
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
port: 80
|
||||
tls:
|
||||
secretName: ${CRT_TLS_NAME}
|
||||
|
||||
|
|
@ -127,35 +130,35 @@ spec:
|
|||
affinity:
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- ${CI_PROJECT_PATH_SLUG}-app
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
namespaces: [$KUBE_NAMESPACE]
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- ${CI_PROJECT_PATH_SLUG}-app
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
namespaces: [$KUBE_NAMESPACE]
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
|
||||
image: $IMAGE_TAG
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "php"
|
||||
args:
|
||||
- "artisan"
|
||||
- "schedule:run"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
volumes:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
|
||||
image: $IMAGE_TAG
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "php"
|
||||
args:
|
||||
- "artisan"
|
||||
- "schedule:run"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
|
|
|
|||
BIN
resources/assets/images/common/wood-bg-blue.jpg
Normal file
BIN
resources/assets/images/common/wood-bg-blue.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
|
|
@ -41,7 +41,7 @@
|
|||
position: absolute;
|
||||
top: -1rem;
|
||||
right: 0;
|
||||
max-width: 55%;
|
||||
max-width: 50%;
|
||||
height: 110%;
|
||||
|
||||
img {
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
}
|
||||
|
||||
@include media-breakpoint-up(xxl) {
|
||||
right: -3rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,32 +22,6 @@
|
|||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.breeding-article-image-wrapper {
|
||||
@include media-breakpoint-up(xl) {
|
||||
position: absolute;
|
||||
top: -1rem;
|
||||
right: 2vw;
|
||||
max-width: 55%;
|
||||
height: 110%;
|
||||
transform: translateX(8vw);
|
||||
|
||||
img {
|
||||
max-width: initial;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xxl) {
|
||||
right: 12vw;
|
||||
max-width: 45%;
|
||||
}
|
||||
|
||||
img {
|
||||
box-shadow: -4px 8px 14px 0 rgb(0 0 0 / 23%);
|
||||
transform: rotate(2deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
resources/sass/fo/pages/commitments.scss
Executable file → Normal file
30
resources/sass/fo/pages/commitments.scss
Executable file → Normal file
|
|
@ -97,7 +97,7 @@
|
|||
}
|
||||
|
||||
.row {
|
||||
width: 390px;
|
||||
width: 100%;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 500px;
|
||||
|
|
@ -413,14 +413,36 @@
|
|||
}
|
||||
|
||||
#commitments-banner-text-complex-items {
|
||||
.banner-title {
|
||||
color: #000;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
position: absolute;
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-custom-placement {
|
||||
z-index: 1;
|
||||
transform: translateY(5rem);
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
transform: translateY(5rem);
|
||||
}
|
||||
}
|
||||
|
||||
~#commitments-complex-flex-items .container {
|
||||
padding-top: 6rem !important;
|
||||
}
|
||||
|
||||
.responsive-position {
|
||||
position: relative;
|
||||
|
||||
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#commitments-paragraph-with-visual,
|
||||
|
|
@ -429,13 +451,13 @@
|
|||
.pictogram {
|
||||
top: -3rem;
|
||||
left: -2rem;
|
||||
width: 8rem;
|
||||
width: 6rem;
|
||||
|
||||
&-reversed {
|
||||
top: -3rem;
|
||||
right: -2rem;
|
||||
left: auto;
|
||||
width: 8rem;
|
||||
width: 6rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
min-height: 80vh;
|
||||
overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.logo-40 {
|
||||
max-width: calc(100% - 30px);
|
||||
padding-top: 195px;
|
||||
|
|
@ -973,9 +977,9 @@
|
|||
|
||||
.bg {
|
||||
&-blue-dark-wood {
|
||||
background-blend-mode: darken;
|
||||
background-color: $primary;
|
||||
background-image: url('@/images/common/wood-bg-big.jpg');
|
||||
// background-blend-mode: darken;
|
||||
// background-color: $primary;
|
||||
background-image: url('@/images/common/wood-bg-blue.jpg');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
|
|
|||
|
|
@ -7,11 +7,17 @@
|
|||
height: 2rem;
|
||||
}
|
||||
|
||||
.swiper-recruitment-offers img {
|
||||
width: 100%;
|
||||
.swiper-recruitment-offers {
|
||||
img {
|
||||
width: 100%;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 50%;
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +34,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
&-news-corporate{
|
||||
&-news-corporate {
|
||||
.swiper-recruitment-news-corporates-pagination {
|
||||
height: 25px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
.product-card {
|
||||
.product-card-tag {
|
||||
top: -5%;
|
||||
|
|
@ -36,6 +35,10 @@
|
|||
.product-card-bottom-part {
|
||||
top: -1rem;
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
min-height: 8.5rem;
|
||||
}
|
||||
|
||||
.product-card-view-more {
|
||||
margin-bottom: -1rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
.testimonial-card {
|
||||
.testimonial-img {
|
||||
clip-path: polygon(60% .2vw,100% 0,100% calc(100% - .2vw),70% calc(100% - .35vw),40% 100%,0 calc(100% - .2vw),0 .2vw,30% 0);
|
||||
clip-path: polygon(60% .2vw, 100% 0, 100% calc(100% - .2vw), 70% calc(100% - .35vw), 40% 100%, 0 calc(100% - .2vw), 0 .2vw, 30% 0);
|
||||
|
||||
&-wrapper {
|
||||
@include media-breakpoint-up(lg) {
|
||||
|
|
@ -36,4 +35,13 @@
|
|||
min-height: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-play {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.video-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,19 +24,43 @@
|
|||
.w#{$infix}-25 {
|
||||
width: 25% !important;
|
||||
}
|
||||
|
||||
.w#{$infix}-50 {
|
||||
width: 50% !important;
|
||||
}
|
||||
|
||||
.w#{$infix}-75 {
|
||||
width: 75% !important;
|
||||
}
|
||||
|
||||
.w#{$infix}-100 {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.w#{$infix}-fit {
|
||||
width: fit-content !important;
|
||||
}
|
||||
|
||||
.h#{$infix}-25 {
|
||||
height: 25% !important;
|
||||
}
|
||||
|
||||
.h#{$infix}-50 {
|
||||
height: 50% !important;
|
||||
}
|
||||
|
||||
.h#{$infix}-75 {
|
||||
height: 75% !important;
|
||||
}
|
||||
|
||||
.h#{$infix}-100 {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.h#{$infix}-fit {
|
||||
height: fit-content !important;
|
||||
}
|
||||
|
||||
@each $prop, $unit in (width: vw, height: vh) {
|
||||
@each $size in [25, 50, 75, 100] {
|
||||
.#{$unit}#{$infix}-#{$size} {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
"swiper-recruitment-offers": {
|
||||
modules: [Navigation, Keyboard, Pagination],
|
||||
grabCursor: true,
|
||||
slidesPerView: 1.3,
|
||||
slidesPerView: 1,
|
||||
initialSlide: 0,
|
||||
spaceBetween: 10,
|
||||
navigation: {
|
||||
|
|
@ -165,6 +165,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
576: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 25,
|
||||
slidesPerGroup: 2,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 2,
|
||||
|
|
@ -179,7 +180,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
"swiper-recruitment-jobs": {
|
||||
modules: [Navigation, Keyboard, Pagination],
|
||||
grabCursor: true,
|
||||
slidesPerView: 1.3,
|
||||
slidesPerView: 1,
|
||||
centeredSlides: true,
|
||||
spaceBetween: 10,
|
||||
navigation: {
|
||||
|
|
@ -203,15 +204,16 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
992: {
|
||||
slidesPerView: 3,
|
||||
initialSlide: 1,
|
||||
slidesPerGroup: 3
|
||||
},
|
||||
},
|
||||
},
|
||||
"swiper-recruitment-news-corporates": {
|
||||
modules: [Navigation, Keyboard, Pagination],
|
||||
grabCursor: true,
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 1,
|
||||
slidesPerGroup: 3,
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 40,
|
||||
centerInsufficientSlides: true,
|
||||
navigation: {
|
||||
nextEl: ".swiper-recruitment-news-corporates-button-next",
|
||||
prevEl: ".swiper-recruitment-news-corporates-button-prev",
|
||||
|
|
@ -227,6 +229,16 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
return "<button class=\"btn btn-tertiary rounded-circle border-0 mx-2 p-0 " + className + "\" title=\"Aller à la slide " + index + "\"></button>";
|
||||
},
|
||||
},
|
||||
breakpoints: {
|
||||
576: {
|
||||
slidesPerView: 2,
|
||||
slidesPerGroup: 2,
|
||||
},
|
||||
992: {
|
||||
slidesPerView: 3,
|
||||
slidesPerGroup: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
"swiper-main-slides": {
|
||||
modules: [Autoplay, Navigation, Keyboard],
|
||||
|
|
@ -283,7 +295,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
"swiper-cards-commitments": {
|
||||
modules: [Navigation],
|
||||
grabCursor: true,
|
||||
slidesPerView: 1.3,
|
||||
slidesPerView: 1,
|
||||
navigation: {
|
||||
nextEl: "#swiper-cards-commitments ~ .swiper-cards-commitments-button-next",
|
||||
prevEl: "#swiper-cards-commitments ~ .swiper-cards-commitments-button-prev",
|
||||
|
|
@ -346,9 +358,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
},
|
||||
},
|
||||
"swiper-recipes": {
|
||||
modules: [Navigation],
|
||||
modules: [Navigation, Pagination],
|
||||
grabCursor: true,
|
||||
slidesPerView: 1.5,
|
||||
slidesPerView: 1,
|
||||
centeredSlides: true,
|
||||
spaceBetween: 20,
|
||||
navigation: {
|
||||
|
|
@ -363,6 +375,14 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
992: {
|
||||
slidesPerView: 3,
|
||||
centeredSlides: false,
|
||||
slidesPerGroup: 3,
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
el: ".swiper-recipe-pagination",
|
||||
clickable: true,
|
||||
renderBullet: function (index: number, className: string) {
|
||||
return "<button class=\"" + className + "\" title=\"Aller à la slide " + (index + 1) + "\"></button>";
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -489,7 +509,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
"swiper-cards-breeder-pages": {
|
||||
modules: [Navigation],
|
||||
grabCursor: true,
|
||||
slidesPerView: 1.3,
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 40,
|
||||
centerInsufficientSlides: true,
|
||||
navigation: {
|
||||
|
|
@ -546,6 +566,32 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
document.querySelector("#swiper-videos .swiper-slide-next")?.setAttribute("inert", "true");
|
||||
});
|
||||
}
|
||||
if (swiper.el.id === "swiper-testimonials") {
|
||||
swiper.on("slideChange", function() {
|
||||
updateTestimonialVideoModal(swiper.slides[swiper.activeIndex]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateTestimonialVideoModal(currentSlide: any) {
|
||||
const videoLinkElement = currentSlide.querySelector(".video-link") as HTMLAnchorElement;
|
||||
if (!videoLinkElement) {
|
||||
return;
|
||||
}
|
||||
const videoModal = document.querySelector("#testimonial-video-modal") as HTMLDivElement;
|
||||
if (!videoModal) {
|
||||
return;
|
||||
}
|
||||
const modalLink = document.querySelector(".video-inlaid") as HTMLAnchorElement;
|
||||
if (!modalLink) {
|
||||
return;
|
||||
}
|
||||
modalLink.setAttribute("href", String(videoLinkElement.dataset.videoLink));
|
||||
const iframe = modalLink.querySelector("iframe");
|
||||
if (!iframe) {
|
||||
return;
|
||||
}
|
||||
iframe.setAttribute("src", String(videoLinkElement.dataset.videoLink));
|
||||
}
|
||||
|
||||
function eventBtnPlayPause(swiper: Swiper, btnPlayPause: HTMLElement | null) {
|
||||
|
|
|
|||
|
|
@ -213,10 +213,10 @@
|
|||
<!-- BUTTONS -->
|
||||
<div
|
||||
v-if="contentParameters.swiper"
|
||||
class="col-12 d-flex flex-column flex-md-row justify-content-center align-items-center w-100"
|
||||
class="col-12 d-flex flex-column flex-md-row justify-content-center align-items-center w-75 w-md-100 mx-auto"
|
||||
>
|
||||
<a
|
||||
class="content-btns btn btn-primary border-0 my-1 my-md-0 mx-md-1"
|
||||
class="content-btns btn btn-primary border-0 my-1 my-md-0 mx-md-1 w-100 w-md-fit"
|
||||
:href="getShowLegendRoute(legendsParameters.modelSelected?.slug as string)"
|
||||
title="Accéder à la page de tous les produits de la gamme"
|
||||
:style="'background-color:' + legendsParameters.modelSelected?.color"
|
||||
|
|
@ -224,7 +224,7 @@
|
|||
{{ (legendsParameters.modelSelected) ? textsParameters.btn1Label + " " + legendsParameters.modelSelected?.label : textsParameters.btn1Label }}
|
||||
</a>
|
||||
<a
|
||||
class="content-btns btn btn-secondary border-0 my-1 my-md-0 mx-md-1"
|
||||
class="content-btns btn btn-secondary border-0 my-1 my-md-0 mx-md-1 w-100 w-md-fit"
|
||||
:href="getIndexContentRoute()"
|
||||
title="Accéder à la page de tous les produits"
|
||||
>
|
||||
|
|
@ -245,8 +245,8 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import Swiper from "swiper";
|
||||
import { Navigation } from "swiper/modules";
|
||||
import { defineOptions, nextTick, onMounted, ref, useAttrs, reactive, createApp } from "vue";
|
||||
import type { App } from "vue";
|
||||
import { createApp, defineOptions, nextTick, onMounted, reactive, ref, useAttrs } from "vue";
|
||||
import route from "../../modules/route";
|
||||
import trans from "../../modules/trans";
|
||||
import parseLaravelErrorMessages from "./../../modules/parseLaravelErrorMessages";
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
>
|
||||
<!-- TEXTS MOBILE -->
|
||||
<div class="d-md-none col-12 col-md-7 col-xl-8 text-center">
|
||||
<h2 ref="modelSubtitle">
|
||||
<h2 ref="modelSubtitleMobile">
|
||||
{{ textsParameters.subtitle }}
|
||||
</h2>
|
||||
<p
|
||||
ref="modelDescription"
|
||||
ref="modelDescriptionMobile"
|
||||
v-html="textsParameters.description"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -319,6 +319,8 @@ const filtersList = ref<HTMLDivElement|null>(null);
|
|||
const childrenList = ref<HTMLDivElement|null>(null);
|
||||
const modelSubtitle = ref<HTMLTitleElement|null>(null);
|
||||
const modelDescription = ref<HTMLParagraphElement|null>(null);
|
||||
const modelSubtitleMobile = ref<HTMLTitleElement|null>(null);
|
||||
const modelDescriptionMobile = ref<HTMLParagraphElement|null>(null);
|
||||
|
||||
// * DATA
|
||||
|
||||
|
|
@ -457,6 +459,8 @@ function updateTexts(newTitle: string|null = null): void {
|
|||
: filtersDetailsParameters.selectedModel;
|
||||
modelSubtitle.value!.textContent = String(((currentModelSelected !== null) ? currentModelSelected : textsParameters).subtitle);
|
||||
modelDescription.value!.innerHTML = String(((currentModelSelected !== null) ? currentModelSelected : textsParameters).description);
|
||||
modelSubtitleMobile.value!.textContent = String(((currentModelSelected !== null) ? currentModelSelected : textsParameters).subtitle);
|
||||
modelDescriptionMobile.value!.innerHTML = String(((currentModelSelected !== null) ? currentModelSelected : textsParameters).description);
|
||||
let parentTitle = (filtersDetailsParameters.selectedChildModel !== null)
|
||||
? filtersDetailsParameters.selectedModel?.label + ", "
|
||||
: "";
|
||||
|
|
|
|||
|
|
@ -15,57 +15,14 @@
|
|||
<div class="card">
|
||||
<div class="card-header fw-bold">{{ __('Connexion') }}</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('bo.login') }}">
|
||||
@csrf
|
||||
<div class="row mb-3">
|
||||
<label class="col-md-4 col-form-label text-md-end" for="email">{{ __('Adresse Email') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control @error('email') is-invalid @enderror" id="email" name="email"
|
||||
type="email" value="{{ old('email') }}" autocomplete="email" autofocus required>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a class="btn btn-primary" href="{{ route('saml.login', ['uuid' => config('saml2.default_tenant_uuid')]) }}">
|
||||
<span>{{ __('Connexion avec UWIL Support') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label class="col-md-4 col-form-label text-md-end" for="password">{{ __('Mot de passe') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control @error('password') is-invalid @enderror" id="password" name="password"
|
||||
type="password" autocomplete="current-password" required>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" id="remember" name="remember" type="checkbox"
|
||||
{{ old('remember') ? 'checked' : '' }}>
|
||||
<label class="form-check-label user-select-none" for="remember">
|
||||
{{ __('Se souvenir de moi') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<span>{{ __('Connexion') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</button>
|
||||
@if (Route::has('bo.password.request'))
|
||||
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
|
||||
{{ __('Mot de passe oublié ?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
@stack('styles')
|
||||
|
||||
@if (config('app.debug'))
|
||||
<script nonce="{{ $nonce }}">
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
window.vueDebug = true;
|
||||
</script>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -8,20 +8,27 @@
|
|||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
</div>
|
||||
<div class="border-start-0 border-end-0 border-bottom-0 border-secondary mt-2 border border-2">
|
||||
<h5 class="card-title py-2">
|
||||
<h5 class="card-title py-2 fw-bold">
|
||||
{{ __('Bonjour :first_name :last_name !', [
|
||||
'first_name' => auth('backend')->user()->first_name,
|
||||
'last_name' => auth('backend')->user()->last_name,
|
||||
]) }}
|
||||
</h5>
|
||||
<p class="card-text m-0">
|
||||
<p class="card-text">
|
||||
{{ __('Bienvenue dans le back-office, où vous pouvez gérer votre application web.') }}
|
||||
</p>
|
||||
<p class="card-text">
|
||||
{{ __('Pour accéder à vos statistiques') }} :
|
||||
<a class="btn btn-primary btn-sm" data-bs-toggle="tooltip" href="https://report.uwil.fr"
|
||||
title="{{ __('Accéder à notre outil de ticketing') }}" target="blank">
|
||||
{{ __('UWIL Report') }}
|
||||
<i class="fa-solid fa-arrow-up-right-from-square ms-1"></i>
|
||||
</a>
|
||||
<br>
|
||||
{{ __('Pour tout problème ou évolution souhaitée, veuillez nous contacter via notre outil : ') }}
|
||||
<a class="btn btn-primary btn-sm" data-bs-toggle="tooltip" href="https://support.uwil.fr/"
|
||||
title="{{ __('Accéder à notre outil de ticketing') }}" target="blank">
|
||||
{{ __('Uwil Support') }}
|
||||
{{ __('UWIL Support') }}
|
||||
<i class="fa-solid fa-arrow-up-right-from-square ms-1"></i>
|
||||
</a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
src="{{ $discountModel->mobile_image_available ?? $discountModel->desktop_image_available }}"
|
||||
alt="{{ __('Bon de réduction :name', ['name' => $discountModel->name]) }}">
|
||||
</td>
|
||||
<td class="text-center align-middle">@money($discountModel->value * 100)</td>
|
||||
<td class="text-center align-middle">@money($discountModel->value)</td>
|
||||
<td class="text-center align-middle">
|
||||
<span class="badge text-bg-secondary">{{ $discountModel->updated_at->isoFormat('LLLL') }}</span>
|
||||
</td>
|
||||
|
|
|
|||
22
resources/views/bo/pages/login-error.blade.php
Normal file
22
resources/views/bo/pages/login-error.blade.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
@extends('fo.layout')
|
||||
|
||||
@section('title', __('Une erreur est survenue lors de la connexion.'))
|
||||
@section('description', __('Il semble qu\'il y ait des erreurs pour répondre à votre demande.'))
|
||||
@section('breadcrumb', 'no')
|
||||
@section('bodyClass', 'bg-white-wood')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5 py-5">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h1>{{ str(__('Une erreur est survenue lors de la connexion.'))->upper() }}</h1>
|
||||
<h4 class="h4 my-4">
|
||||
{{ __('Veuillez contacter le support.') }}
|
||||
</h4>
|
||||
<a class="btn btn-secondary" href="{{ route('fo.home.show') }}" title="{{ __('Accéder à la page d\'accueil') }}">
|
||||
{{ str(__('retour à la page d\'accueil'))->upper() }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
@use('\App\Enums\StaticPageType', 'StaticPageType')
|
||||
<div class="row">
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product))
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recipe) && !$staticPageModel->type->equals(StaticPageType::product))
|
||||
{{-- SEO_TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
|
|
@ -80,9 +79,10 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
@endif
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home))
|
||||
@if (
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home))
|
||||
{{-- TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
|
|
@ -112,12 +112,13 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
@endif
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::legals) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::confidentiality) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::accessibility) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::selling))
|
||||
@if (
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::legals) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::confidentiality) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::accessibility) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::selling))
|
||||
{{-- SUBTITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
|
|
@ -142,7 +143,7 @@
|
|||
'model' => trans_choice('models.classes.static_page', 1),
|
||||
]),
|
||||
'min' => 3,
|
||||
'max' => 255,
|
||||
'max' => 500,
|
||||
]),
|
||||
'placeholder' => __(':field :inter:model', [
|
||||
'field' => str(__('validation.custom.subtitle'))->ucfirst(),
|
||||
|
|
@ -155,10 +156,11 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
@endif
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recruitment) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home))
|
||||
@if (
|
||||
!$staticPageModel->type->equals(StaticPageType::recruitment) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home))
|
||||
{{-- CONTENT --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="border p-3">
|
||||
|
|
@ -189,15 +191,16 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
@endif
|
||||
@if (!$staticPageModel->type->equals(StaticPageType::recipes) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::products) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::legals) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::confidentiality) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::accessibility) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::selling))
|
||||
@if (
|
||||
!$staticPageModel->type->equals(StaticPageType::recipes) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::recipe) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::products) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::product) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::home) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::legals) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::confidentiality) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::accessibility) &&
|
||||
!$staticPageModel->type->equals(StaticPageType::selling))
|
||||
{{-- PICTURE SECTION --}}
|
||||
<div class="col-12 pb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
|
|
|
|||
|
|
@ -89,39 +89,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- PASSWORD --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ __('Mot de passe') }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword',
|
||||
'label' => __('Mot de passe de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'password',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __(
|
||||
'Doît respecter certaines contraintes (8 caractères minimum, lettres, chiffres, caractères spéciaux).'),
|
||||
])
|
||||
</div>
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword_confirmation',
|
||||
'label' => __('Confirmation du mot de passe de l\':model', [
|
||||
'model' => __('models.classes.user'),
|
||||
]),
|
||||
'name' => 'password_confirmation',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __('Doît correspondre au mot de passe saisi précédemment.'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- STATUS --}}
|
||||
@can('changePublished', $userModel)
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
|
|
@ -145,20 +112,3 @@
|
|||
<p><b>{{ __('* Champs obligatoires') }}</b></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script nonce="{{ $nonce }}">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// If we edit the password, the confirmation is required.
|
||||
const passwordInput = document.getElementById('userPassword');
|
||||
const confirmPasswordInput = document.getElementById('userPassword_confirmation');
|
||||
passwordInput.addEventListener('input', () => {
|
||||
if (passwordInput.value !== '') {
|
||||
confirmPasswordInput.required = true;
|
||||
} else {
|
||||
confirmPasswordInput.required = false;
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
@push('scripts')
|
||||
<script nonce="{{ $nonce }}">
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const submit = document.getElementById('formSubmit')
|
||||
submitClone = document.getElementById('formSubmitClone');
|
||||
|
|
|
|||
|
|
@ -49,12 +49,11 @@
|
|||
id="accept-cgu" name="ok_cgu" type="checkbox" required />
|
||||
<label class="form-check-label w-fit" for="accept-cgu" role="button">
|
||||
<span>{!! clean(__('J’accepte les conditions générales d’utilisation du site et autorise le Responsable de Traitement à traiter mes données personnelles conformément à la :startA Charte de confidentialité:endA.', [
|
||||
'startA' =>
|
||||
'<a class="link-body-emphasis" title="' .
|
||||
__('Go to page :page', [
|
||||
'page' => __('Charte de confidentialité'),
|
||||
]) .
|
||||
'" href="FIXME: privacy policy route">',
|
||||
'startA' => sprintf(
|
||||
'<a class="link-body-emphasis" target="_blank" title="%s" href="%s">',
|
||||
__('Go to page :page', ['page' => __('Charte de confidentialité')]),
|
||||
route('fo.policies.show')
|
||||
),
|
||||
'endA' => '</a>',
|
||||
])) !!}</span>
|
||||
</label>
|
||||
|
|
@ -89,12 +88,11 @@
|
|||
__(
|
||||
'Les informations recueillies à partir de ce formulaire sont traitées par le Responsable de Traitement pour la création de votre compte utilisateur. Pour connaître vos droits, vous pouvez consulter la :startA Charte de confidentialité:endA.',
|
||||
[
|
||||
'startA' =>
|
||||
'<a class="link-body-emphasis" title="' .
|
||||
__('Go to page :page', [
|
||||
'page' => __('Charte de confidentialité'),
|
||||
]) .
|
||||
'" href="FIXME: privacy policy route">',
|
||||
'startA' => sprintf(
|
||||
'<a class="link-body-emphasis" target="_blank" title="%s" href="%s">',
|
||||
__('Go to page :page', ['page' => __('Charte de confidentialité')]),
|
||||
route('fo.policies.show')
|
||||
),
|
||||
'endA' => '</a>',
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -115,13 +115,13 @@
|
|||
{{ __('© Copyright :appname', ['appname' => config('app.name')]) }}</li>
|
||||
<li class="list-inline-item me-0">-</li>
|
||||
<li class="list-inline-item me-0">
|
||||
<a href="#FIXME:legals"
|
||||
<a href="{{ route('fo.legals.show') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Mentions légales et CGU Charte de confidentialité']) }}">
|
||||
{{ __('Mentions légales et CGU Charte de confidentialité') }}</a>
|
||||
</li>
|
||||
<li class="list-inline-item me-0">-</li>
|
||||
<li class="list-inline-item me-0">
|
||||
<a href="#FIXME:confidentiality"
|
||||
<a href="{{ route('fo.conditions.show') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'CGV']) }}">{{ __('CGV') }}</a>
|
||||
</li>
|
||||
<li class="list-inline-item me-0">-</li>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
'line2' => __('Dès aujourd’hui'),
|
||||
'line2Class' => 'fs-4',
|
||||
'content' => __('Spécial étudiant, Spécial famille, Spécial membre'),
|
||||
'promoAmount' => 770 //FIXME: call mesbr,
|
||||
'promoAmount' => $discountsTotal
|
||||
])
|
||||
@include('club.partials.card-club-home', [
|
||||
'outterClass' => 'm-3',
|
||||
|
|
@ -67,11 +67,11 @@
|
|||
<section class="container-fluid d-sm-none">
|
||||
<div class="row my-3">
|
||||
<div class="col d-flex flex-column align-items-center">
|
||||
<a class="btn btn-secondary btn-lg flex-shrink-1 mb-3" href="#FIXME:register"
|
||||
<a class="btn btn-secondary btn-lg flex-shrink-1 mb-3" href="{{ route('club.register') }}"
|
||||
title="{{ __('Go to page :page', [
|
||||
'page' => __('Inscription'),
|
||||
]) }}">{{ __('Je m\'inscris') }}</a>
|
||||
<a class="link-light link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="#FIXME:login"
|
||||
<a class="link-light link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover" href="{{ route('club.login') }}"
|
||||
title="{{ __('Go to page :page', [
|
||||
'page' => __('Connexion'),
|
||||
]) }}">{{ __('J\'ai déjà un compte') }}</a>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
<div class="text-bg-white rounded-5 fs-5 p-5 pt-0 text-center">
|
||||
<h2 class="section-title text-uppercase f-bourton-base">
|
||||
<span class="text-bg-warning">{{ __('Économiser aujourd’hui') }}</span><span
|
||||
class="text-bg-danger">@money($discountsTotal * 100)</span>
|
||||
class="text-bg-danger">@money($discountsTotal)</span>
|
||||
</h2>
|
||||
<span
|
||||
class="d-block fw-bold mb-3">{{ __('En bons de réduction sur une sélection de produits Le Gaulois') }}</span>
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
<div class="d-none d-md-block text-bg-white col-12 mt-5 pb-5 text-center">
|
||||
<h2 class="section-title text-uppercase f-bourton-base d-none d-md-inline-flex">
|
||||
<span class="text-bg-warning">{{ __('Économiser aujourd’hui') }}</span>
|
||||
<span class="text-bg-danger">@money($discountsTotal * 100)</span>
|
||||
<span class="text-bg-danger">@money($discountsTotal)</span>
|
||||
</h2>
|
||||
<span class="d-block fs-5 fw-bold mb-5">
|
||||
{{ __('En bons de réduction sur une sélection de produits Le Gaulois') }}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<div class="col-7">
|
||||
<div
|
||||
class="card-body d-flex flex-column justify-content-between align-items-start rounded-5 rounded-start-0 text-bg-white">
|
||||
<span class="text-bg-danger f-bourton-base fw-bold fs-1 px-2 py-1">@money($discount->value * 100)</span>
|
||||
<span class="text-bg-danger f-bourton-base fw-bold fs-1 px-2 py-1">@money($discount->value)</span>
|
||||
<p class="card-text f-bourton-base text-tertiary text-start fs-6 my-1">{{ $discount->name }}</p>
|
||||
@if (!isset($discount->used) || !$discount->used)
|
||||
@if (request()->routeIs('club.home.show'))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="container mt-5">
|
||||
<div class="mb-lg-5 container mt-5">
|
||||
<div class="navigation-card bg-light position-relative line-border-small light-card-content text-primary mx-auto mt-3 px-3 py-4">
|
||||
<nav class="d-flex justify-content-md-center" aria-label="breadcrumb">
|
||||
<ol class="breadcrumb text-primary">
|
||||
|
|
@ -11,30 +11,31 @@
|
|||
</nav>
|
||||
|
||||
<p class="fs-5 text-md-center pr-3 text-start">
|
||||
Depuis <strong> 40 ans</strong>, Le Gaulois s'engage à proposer des produits <strong>100% origine France</strong> avec
|
||||
des volailles
|
||||
nées, élevées et
|
||||
préparées sur notre territoire. 40 ans de convivialité et de plaisir à la française, <strong>à partager avec vous
|
||||
!</strong> Pendant
|
||||
cette année festive, découvrez <strong>nos jeux et nos surprises</strong>.
|
||||
{!! clean(
|
||||
__(
|
||||
'Depuis 40 ans, Le Gaulois s\'engage à proposer des produits <strong>100% origine France</strong> avec des <strong>volailles nées, élevées et préparées</strong> sur notre territoire. <br>
|
||||
<strong>40 ans de convivialité et de plaisir à la française, à partager avec vous !</strong> <br>
|
||||
Pendant cette année festive, découvrez <strong>nos jeux et nos surprises</strong>.',
|
||||
),
|
||||
) !!}
|
||||
</p>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-center mt-4 gap-4">
|
||||
<div class="text-md-start text-center">
|
||||
<a class="btn text-uppercase w-100 w-md-fit btn-cotillons f-bourton-base fw-medium px-md-3 px-0 py-2 text-white"
|
||||
href="#nos-40-annees">
|
||||
Nos 40 années
|
||||
{{ __('Nos 40 années') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-md-start text-center">
|
||||
<a class="btn text-uppercase w-100 w-md-fit btn-cotillons f-bourton-base fw-medium px-md-3 px-0 py-2 text-white"
|
||||
href="#le-jeu-des-40-ans">
|
||||
Jouez avec nous !
|
||||
{{ __('Jouez avec nous !') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-md-start text-center">
|
||||
<a class="btn text-uppercase w-100 w-md-fit btn-cotillons f-bourton-base fw-medium px-md-3 px-0 py-2 text-white"
|
||||
href="#encore-plus-de-cadeaux">
|
||||
Encore + de cadeaux !
|
||||
{{ __('Encore + de cadeaux !') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
<h2 class="fs-1 f-bourton-base text-primary text-center">L'anniversaire de <span class="bg-danger text-white shadow-sm">68
|
||||
millions</span>
|
||||
de Gaulois
|
||||
!</h2>
|
||||
<p class="fs-5 text-primary py-md-4 py-2 text-center">Pour notre 40e anniversaire, nous célébrons avec nos 68 millions de
|
||||
Gaulois, notre
|
||||
attachement pour des
|
||||
produits français et
|
||||
authentiques, qui reflètent nos valeurs de qualité, accessibilité et de transparence.
|
||||
<h2 class="fs-1 f-bourton-base text-primary text-center">
|
||||
{{ __('L\'anniversaire de') }}
|
||||
<span class="bg-danger text-white shadow-sm">
|
||||
{{ __('68 millions') }}
|
||||
</span>
|
||||
{{ __('de Gaulois !') }}
|
||||
</h2>
|
||||
<p class="fs-5 text-primary py-md-4 py-2 text-center">
|
||||
{!! clean(
|
||||
__(
|
||||
'Pour notre <strong>40e anniversaire</strong>, nous célébrons avec nos <strong>68 millions de Gaulois</strong>, notre attachement pour des produits <strong>français et authentiques</strong>, qui reflètent nos <strong>valeurs de qualité, accessibilité et de transparence.</strong>',
|
||||
),
|
||||
) !!}
|
||||
</p>
|
||||
<h3 class="text-primary fs-3 text-center">Bon anniversaire à tous nos Gaulois !</h3>
|
||||
<h3 class="text-primary fs-3 text-center">{{ __('Bon anniversaire à tous nos Gaulois !') }}</h3>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,5 @@
|
|||
</div>
|
||||
<img class="object-fit-fill" id="drapeau-france"
|
||||
src="{{ Vite::asset('resources/assets/images/page-des-40-ans/section2/drapeau.svg') }}" alt="{{ __('Photo drapeau France') }}">
|
||||
|
||||
</div>
|
||||
<small class="text-primary f-catamaran credit-photo">Crédit photo -</small>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="bg-confettis-without-min-height position-absolute h-100 w-100 z-1 start-0 top-0"></div>
|
||||
<div class="bg-blue-dark-wood">
|
||||
<div class="z-2 position-relative container-fluid container py-4" id="encore-plus-de-cadeaux">
|
||||
<h3 class="fs-2 pt-5 text-center text-white">Encore + de cadeaux à gagner</h3>
|
||||
<h3 class="fs-2 pt-5 text-center text-white">{{ __('Encore + de cadeaux à gagner') }}</h3>
|
||||
|
||||
<div class="py-5">
|
||||
<div class="row gx-4 gy-5">
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
<div class="gradient-yellow-card bg-gradient-yellow position-relative line-border-small w-fit p-1">
|
||||
<div class="">
|
||||
<div class="bg-light position-relative line-border-small p-4">
|
||||
<h4 class="text-primary text-center">Collectez des points et choisissez vos cadeaux dans notre
|
||||
boutique
|
||||
<h4 class="text-primary text-center">
|
||||
{{ __('Collectez des points et choisissez vos cadeaux dans notre boutique') }}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-6 d-flex flex-column">
|
||||
|
|
@ -21,8 +21,10 @@
|
|||
src="{{ Vite::asset('resources/assets/images/page-des-40-ans/section4/sticker-boutique.png') }}"
|
||||
alt="{{ __('Image de sticker de la boutique') }}">
|
||||
</div>
|
||||
<p class="f-bourton-base fs-5 text-uppercase text-primary text-center">1€ dépensé = <br /> 1
|
||||
point collecté</p>
|
||||
<p class="f-bourton-base fs-5 text-uppercase text-primary text-center">
|
||||
{{ __('1€ dépensé = ') }}<br />
|
||||
{{ __('1 point collecté') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
|
|
@ -45,8 +47,9 @@
|
|||
|
||||
</div>
|
||||
|
||||
<p class="f-bourton-base fs-5 text-uppercase text-primary text-center">2 paliers, <br /> de
|
||||
nombreux cadeaux
|
||||
<p class="f-bourton-base fs-5 text-uppercase text-primary text-center">
|
||||
{{ __('2 paliers, ') }}<br />
|
||||
{{ __('de nombreux cadeaux') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -58,8 +61,9 @@
|
|||
</div>
|
||||
|
||||
<a class="button-gradient-yellow btn text-uppercase text-primary bg-gradient-yellow"
|
||||
href="https://www.boutiquelegaulois.fr" target="_blank">Découvrez
|
||||
notre boutique</a>
|
||||
href="https://www.boutiquelegaulois.fr" target="_blank">
|
||||
{{ __('Découvrez notre boutique') }}
|
||||
</a>
|
||||
|
||||
<div class="image-cadeau-rouge align-self-center">
|
||||
<img class="object-fit-contain h-100 w-100"
|
||||
|
|
@ -74,24 +78,28 @@
|
|||
<div class="bg-gradient-yellow gradient-yellow-card position-relative line-border-small w-fit p-1">
|
||||
<div class="">
|
||||
<div class="bg-light position-relative line-border-small p-4">
|
||||
<h4 class="text-primary text-center">Trouvez les magnets dorés <br /> et remportez une surpise !
|
||||
<h4 class="text-primary text-center">
|
||||
{{ __('Trouvez les magnets dorés') }}<br />
|
||||
{{ __('et remportez une surpise !') }}
|
||||
</h4>
|
||||
<p class="f-bourton-base text-primary fw-medium fs-5 text-uppercase mt-3 text-center">
|
||||
Pour ses 40 ans, le gaulois a caché 94 magnets dorés <br /> dans ses étuis de panés
|
||||
{{ __('Pour ses 40 ans, le gaulois a caché 94 magnets dorés') }}<br />
|
||||
{{ __('dans ses étuis de panés') }}
|
||||
</p>
|
||||
|
||||
<ol class="text-primary ordered-list-centered-with-number">
|
||||
<li class="lh-lg">
|
||||
<strong>Je découvre</strong> un Magnet doré
|
||||
<strong>{{ __('Je découvre') }}</strong> {{ __('un magnet doré') }}
|
||||
</li>
|
||||
<li>
|
||||
<strong>Je gagne</strong> une carte de France collector 40 ans créée par un jeune artise
|
||||
français et une collection complète de magnets dorés !
|
||||
<strong>{{ __('Je gagne') }}</strong>
|
||||
{{ __('une carte de France collector 40 ans créée par un jeune artise français et une collection complète de magnets dorés !') }}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p class="text-primary fs-4 fw-semibold f-bakerie-rough text-center">Bonne recherche à nos 68
|
||||
millions de Gaulois !</p>
|
||||
<p class="text-primary fs-4 fw-semibold f-bakerie-rough text-center">
|
||||
{{ __('Bonne recherche à nos 68millions de Gaulois !') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@
|
|||
title="{{ __('Go to page :page', ['page' => 'Nos produits']) }}">{{ __('Nos produits') }}</a>
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.recipes.index') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Nos recettes']) }}">{{ __('Nos recettes') }}</a>
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="#FIXME:nosengagements"
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.commitments.brand') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Nos engagements']) }}">{{ __('Nos engagements') }}</a>
|
||||
</div>
|
||||
<div class="col col-lg-2 d-none d-sm-flex flex-column align-items-baseline">
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="#FIXME:leselevages"
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.breeding.index') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Les élevages']) }}">{{ __('Les élevages') }}</a>
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="#FIXME:brand"
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.brand.story') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Notre marque']) }}">{{ __('Notre marque') }}</a>
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.recruitment.show') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Recrutement']) }}">{{ __('Recrutement') }}</a>
|
||||
|
|
@ -48,8 +48,8 @@
|
|||
<div class="col col-lg-2 ms-lg-auto d-none d-sm-flex flex-column align-items-baseline">
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="{{ route('fo.contact.show') }}"
|
||||
title="{{ __('Go to page :page', ['page' => 'Nous contacter']) }}">{{ __('Nous contacter') }}</a>
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="#FIXME:faq"
|
||||
title="{{ __('Go to page :page', ['page' => 'Faq']) }}">{{ __('Faq') }}</a>
|
||||
{{-- <a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="#FIXME:faq"
|
||||
title="{{ __('Go to page :page', ['page' => 'Faq']) }}">{{ __('Faq') }}</a> --}}
|
||||
<a class="fs-5 text-uppercase btn btn-link text-decoration-none py-2" href="https://www.legauloisprofessionnel.fr"
|
||||
title="{{ __('Aller sur le site Le Gaulois Professionel') }}" target="_blank">{{ __('Le Gaulois Professionel') }}</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<a class="cn-cookie-link" href="#"
|
||||
title="{{ __('Go to page :page', ['page' => 'Gestion des cookies']) }}">{{ __('Gestion des cookies') }}</a>
|
||||
</li>
|
||||
{{-- FIXME:
|
||||
<li class="list-inline-item me-0">-</li>
|
||||
<li class="list-inline-item me-0">
|
||||
<a href="FIXME:#plandusite" title="{{ __('Go to page :page', ['page' => 'Plan du site']) }}">{{ __('Plan du site') }}</a>
|
||||
|
|
@ -26,5 +27,5 @@
|
|||
<li class="list-inline-item me-0">
|
||||
<a href="{{ route('fo.accessibility.show') }}" title="{{ __('Go to page :page', ['page' => 'accessibilité']) }}">{{ __('Accessibilité') }}</a>
|
||||
<span>{{ __(' : partiellement conforme') }}</span>
|
||||
</li>
|
||||
</li> --}}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
{{ __('Devenez un Gaulois ++,') }}<br>{{ __(' et profitez de tous les avantages') }}
|
||||
</p>
|
||||
<a class="card bg-primary position-relative text-decoration-none mx-auto p-3 pb-5"
|
||||
href="#CHANGEME: connexion au club" title="{{ __('Accéder au club des Gaulois') }}">
|
||||
href="{{ route('club.home.show') }}" title="{{ __('Accéder au club des Gaulois') }}">
|
||||
<div class="row hstack mb-3">
|
||||
<div class="col-5 d-flex justify-content-center">
|
||||
<img class="img-fluid w-75" src="{{ Vite::asset('resources/assets/images/header/club-logo.png') }}"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
{{-- DEBUG --}}
|
||||
@if (config('app.debug'))
|
||||
<script @if (!empty($nonce)) nonce="{{ $nonce }}" @endif>
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
window.vueDebug = true;
|
||||
</script>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@
|
|||
],
|
||||
[
|
||||
'name' => __('L\'élevage de volailles'),
|
||||
'link' => route(
|
||||
'fo.breeding.show',
|
||||
$breedingPages->where('type', \App\Enums\StaticPageType::breedingPoultry)->first()),
|
||||
'link' => route('fo.breeding.show', 'slug'),
|
||||
],
|
||||
[
|
||||
'name' => __('Le métier d\'élevage de volailles'),
|
||||
|
|
|
|||
|
|
@ -8,35 +8,40 @@
|
|||
@section('content')
|
||||
<section id="breeding-article">
|
||||
{{-- HEADER --}}
|
||||
<section class="position-relative mb-xl-0 mb-3" id="breeding-article-header">
|
||||
<div class="position-absolute w-100 h-100 start-0 z-0" id="breeding-article-background"></div>
|
||||
<div class="row w-100 container mx-auto pb-5">
|
||||
<div class="col-12 col-xl-6 col-xxl-8 position-relative z-1">
|
||||
<section id="header-banner" @class([
|
||||
'position-relative header-line-border',
|
||||
'mb-5 mb-xl-0' => isset($contentAstride) && $contentAstride,
|
||||
])>
|
||||
<div class="position-absolute w-100 h-100 start-0 z-0" id="header-background"></div>
|
||||
<div class="row w-100 pb-lg-5 container mx-auto pb-0">
|
||||
<div class="col-12 col-xl-6 position-relative z-1">
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => [$staticPageModel, $newsBreedingModel]])
|
||||
<h1 class="text-break my-3">{{ $newsBreedingModel->title }}</h1>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 position-relative z-1">
|
||||
<ul class="d-flex justify-content-start align-items-baseline p-0">
|
||||
<li class="me-2">
|
||||
<p class="text-uppercase text-bg-success f-bourton-base fs-5 px-2 py-1">{{ $staticPageModel->title }}
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
@include('fo.partials.button-share', [
|
||||
'link' => route('fo.breeding.article.show', [$staticPageModel, $newsBreedingModel]),
|
||||
'elementName' => __('cet article'),
|
||||
])
|
||||
</li>
|
||||
</ul>
|
||||
<hgroup>
|
||||
<div class="d-flex justicy-content-center align-items-center">
|
||||
<h1 class="my-3">{{ $newsBreedingModel->title }}</h1>
|
||||
</div>
|
||||
<ul class="d-flex justify-content-start align-items-baseline p-0">
|
||||
<li class="me-2">
|
||||
<p class="text-uppercase text-bg-success f-bourton-base fs-5 px-2 py-1">{{ $staticPageModel->title }}
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
@include('fo.partials.button-share', [
|
||||
'link' => route('fo.breeding.article.show', [$staticPageModel, $newsBreedingModel]),
|
||||
'elementName' => __('cet article'),
|
||||
])
|
||||
</li>
|
||||
</ul>
|
||||
</hgroup>
|
||||
</div>
|
||||
<div class="d-none d-xl-block col-6 col-xxl-4">
|
||||
<div class="breeding-article-image-wrapper">
|
||||
<div class="header-image-wrapper">
|
||||
<img class="img-fluid" src="{{ asset($newsBreedingModel->picture) }}" title="{{ $newsBreedingModel->picture_title }}"
|
||||
alt="{{ $newsBreedingModel->picture_alt }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-xl-none col-12 col-md-8 position-relative z-1 mx-auto mt-4">
|
||||
<div class="breeding-article-image-wrapper">
|
||||
<div class="col-12 col-md-8 position-relative z-1 mx-auto mt-4">
|
||||
<div class="d-xl-none header-image-wrapper">
|
||||
<img class="img-fluid" src="{{ asset($newsBreedingModel->picture) }}" title="{{ $newsBreedingModel->picture_title }}"
|
||||
alt="{{ $newsBreedingModel->picture_alt }}">
|
||||
</div>
|
||||
|
|
@ -44,7 +49,7 @@
|
|||
</div>
|
||||
</section>
|
||||
<section class="container mt-3">
|
||||
<div class="row">
|
||||
<div class="row py-5">
|
||||
<article class="col me-4">
|
||||
<h2 class="text-break">{{ $newsBreedingModel->subtitle }}</h2>
|
||||
<div class="ck-content">
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@
|
|||
'title' => 'L\'élevage des volailles',
|
||||
'text' => nl2br(
|
||||
__(
|
||||
'Face aux préoccupations des consommateurs sur le bien-être animal, Le Gaulois vous dit tout sur ses :strongStartéleveurs partenaires:strongEnd et ses conditions d:strongStart\'élevages de volailles.:strongEnd Chaque jour, nous collaborons avec les éleveurs partenaires engagés dans la démarche éthique et responsable pour améliorer le confort de nos volailles. Chez les éleveurs partenaires Le Gaulois, la protection animale ne cesse d\'être l\'enjeu majeur.',
|
||||
'Face aux préoccupations des consommateurs sur le bien-être animal, Le Gaulois vous dit tout sur ses :strongStartéleveurs partenaires:strongEnd et ses :strongStartconditions d\'élevages de volailles.:strongEnd :br Chaque jour, nous collaborons avec les éleveurs partenaires engagés dans la :strongStartdémarche éthique et responsable:strongEnd pour améliorer le confort de nos volailles. Chez les éleveurs partenaires Le Gaulois, la :strongStartprotection animale:strongEnd ne cesse d\'être l\'enjeu majeur.',
|
||||
[
|
||||
'strongStart' => '<strong>',
|
||||
'strongEnd' => '</strong>',
|
||||
'br' => '<br>',
|
||||
])),
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,11 @@
|
|||
'title' => 'L\'élevage des volailles',
|
||||
'text' => nl2br(
|
||||
__(
|
||||
'Face aux préoccupations des consommateurs sur le bien-être animal, Le Gaulois vous dit tout sur ses :strongStartéleveurs partenaires:strongEnd et ses conditions d:strongStart\'élevages de volailles.:strongEnd Chaque jour, nous collaborons avec les éleveurs partenaires engagés dans la démarche éthique et responsable pour améliorer le confort de nos volailles. Chez les éleveurs partenaires Le Gaulois, la protection animale ne cesse d\'être l\'enjeu majeur.',
|
||||
'Face aux préoccupations des consommateurs sur le bien-être animal, Le Gaulois vous dit tout sur ses :strongStartéleveurs partenaires:strongEnd et ses :strongStartconditions d\'élevages de volailles.:strongEnd :br Chaque jour, nous collaborons avec les éleveurs partenaires engagés dans la :strongStartdémarche éthique et responsable:strongEnd pour améliorer le confort de nos volailles. Chez les éleveurs partenaires Le Gaulois, la :strongStartprotection animale:strongEnd ne cesse d\'être l\'enjeu majeur.',
|
||||
[
|
||||
'strongStart' => '<strong>',
|
||||
'strongEnd' => '</strong>',
|
||||
'br' => '<br>',
|
||||
])),
|
||||
])
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -129,21 +129,6 @@
|
|||
'background_color' => 'white',
|
||||
])
|
||||
{{-- PARAGRAPH WITH PICTURE --}}
|
||||
@php
|
||||
$newsCategory = new stdClass();
|
||||
$newsCategory->title = __('Actu');
|
||||
|
||||
$newsModel = new stdClass();
|
||||
$newsModel->title = __('découvrez notre charte nutritionnelle pour alliers plaisir et santé');
|
||||
$newsModel->slug = str($newsModel->title)->slug();
|
||||
$newsModel->thumbnail = Vite::asset('resources/assets/images/commitments/pictograms/picto-medications.svg');
|
||||
$newsModel->thumbnail_alt = __('Pictogramme de plusieurs médicaments.');
|
||||
$newsModel->thumbnail_title = __('Pictogramme d’une diminution de l’utilisation des antibiotiques.');
|
||||
$newsModel->date = now()->subDays(rand(0, 31));
|
||||
$newsModel->link = 'FIXME: route to the news';
|
||||
$newsModel->newsCategory = $newsCategory;
|
||||
$newsModel->updated_at = now();
|
||||
@endphp
|
||||
@include('fo.partials.commitments.paragraph-with-visual', [
|
||||
'title' => __('découvrez notre charte nutrionnelle pour allier plaisir et santé'),
|
||||
'text' => __(
|
||||
|
|
@ -154,7 +139,6 @@
|
|||
'picture_alt' => __('Photo d’une famille prenant le repas du midi.'),
|
||||
'picture_title' => __('Photo d’une famille prenant le repas du midi.'),
|
||||
'reversedMobile' => true,
|
||||
'newsModel' => $newsModel,
|
||||
])
|
||||
{{-- BANNER TEXT --}}
|
||||
@php
|
||||
|
|
|
|||
|
|
@ -125,22 +125,28 @@
|
|||
])
|
||||
{{-- PARAGRAPH WITH PICTURE --}}
|
||||
@php
|
||||
$newsCategory = new stdClass();
|
||||
$newsCategory->title = __('Actu');
|
||||
|
||||
$newsModel = new stdClass();
|
||||
$newsModel->title = __('découvrez notre charte nutritionnelle pour alliers plaisir et santé');
|
||||
$newsModel->slug = str($newsModel->title)->slug();
|
||||
$newsModel->thumbnail = Vite::asset('resources/assets/images/commitments/pictograms/picto-medications.svg');
|
||||
$newsModel->thumbnail_alt = __('Pictogramme de plusieurs médicaments.');
|
||||
$newsModel->thumbnail_title = __('Pictogramme d’une diminution de l’utilisation des antibiotiques.');
|
||||
$newsModel->date = now()->subDays(rand(0, 31));
|
||||
$newsModel->link = 'FIXME: route to the news';
|
||||
$newsModel->newsCategory = $newsCategory;
|
||||
$newsModel->updated_at = now();
|
||||
$videoID = '63RGcX7_MCM';
|
||||
@endphp
|
||||
<div class="modal fade translate-middle top-50 start-50" id="mecenat-chirurgie-video-modal" aria-labelledby="mecenatChirurgieVideoModalLabel"
|
||||
aria-hidden="true" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button class="btn-close" data-bs-dismiss="modal" type="button" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="video-inlaid ratio ratio-16x9" type="youtube" href="https://www.youtube.com/embed/{{ $videoID }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">{{ __('Fermer') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('fo.partials.commitments.paragraph-with-visual', [
|
||||
'title' => __('2021, nos collaborateurs ont du cœur'),
|
||||
'isVideoModal' => true,
|
||||
'text' => nl2br(
|
||||
__(
|
||||
'Depuis 2021, Le Gaulois soutient l’:strongStartassociation Mécénat Chirurgie Cardiaque:strongEnd pour sauver des enfants en finançant des opérations d’enfants atteint de malformation cardiaque. :strongStartCourse à pied, vélo, marche, randonnée,:strongEnd les kilomètres parcourus sont compilés par une application sportive tout au long de l’année pour récolter un maximum de fonds pour l’association.',
|
||||
|
|
@ -176,13 +182,12 @@
|
|||
'strongEnd' => '</strong>',
|
||||
])),
|
||||
'background_color' => 'light',
|
||||
'video_id' => '63RGcX7_MCM',
|
||||
'video_id' => $videoID,
|
||||
'picto' => Vite::asset('resources/assets/images/commitments/common/logo-mecenat.jpg'),
|
||||
'picto_alt' => __(
|
||||
'Logo de Mécénat Chirurgie Cardiaque, un soutien aux initiatives culturelles et sociales pour promouvoir la solidarité et l\'engagement'),
|
||||
'picto_title' => __('Logo de Mécénat Chirurgie Cardiaque, enfant du monde'),
|
||||
'reversedMobile' => true,
|
||||
'newsModel' => $newsModel,
|
||||
])
|
||||
{{-- OTHER COMMITMENTS --}}
|
||||
@include('fo.partials.commitments.other-commitments', [
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
'title' => __('stop à la déforestation, halte au soja non responsable'),
|
||||
'text' => nl2br(
|
||||
__(
|
||||
'Chez Le Gaulois, pour assurer :strongStartl’apport protéique:strongEnd et assurer un équilibre nutritionnel de nos volailles, nous les alimentons avec du soja. C’est la légumineuse la plus riche en protéines et en acides aminés essentiels ! Conscient que la culture du Soja importée est assujettie à de nombreux questionnements, notamment son impact sur la déforestation.',
|
||||
'Chez Le Gaulois, pour assurer :strongStartl’apport protéique:strongEnd et assurer un :strongStartéquilibre nutritionnel de nos volailles:strongEnd, nous les alimentons avec du :strongStartsoja:strongEnd. C’est la :strongStartlégumineuse la plus riche en protéines et en acides aminés essentiels !:strongEnd Conscient que la culture du Soja importée est assujettie à de nombreux questionnements, notamment son impact sur la :strongStartdéforestation.:strongEnd',
|
||||
[
|
||||
'strongStart' => '<strong>',
|
||||
'strongEnd' => '</strong>',
|
||||
|
|
@ -135,11 +135,17 @@
|
|||
'Conscient de son rôle, Le Gaulois s ‘est engagé dans une démarche continue de réduction de ses emballages et d’amélioration de leur recyclabilité, tout en garantissant la sécurité alimentaire.') .
|
||||
'</br>' .
|
||||
__(
|
||||
'<ul class="mb-3 p-0">Depuis fin 2023, près de 80% de nos emballages sont responsables :<li class="ms-4">soit intégrant de la matière recyclée</li><li class="ms-4">soit en étant recyclables</li></ul>') .
|
||||
__('D’ici fin 2025, nous ambitionnons de passer à près de 95% d’emballages responsables.') .
|
||||
'<ul class="mb-3 p-0">Depuis fin 2023, près de :strongStart80% de nos emballages sont responsables:strongEnd :<li class="ms-4">soit intégrant de la matière recyclée</li><li class="ms-4">soit en étant recyclables</li></ul>',
|
||||
['strongStart' => '<strong>', 'strongEnd' => '</strong>']) .
|
||||
__(
|
||||
'<p>D’ici fin 2025, nous ambitionnons de passer à près de :strongStart95% d’emballages responsables.:strongEnd</p>',
|
||||
[
|
||||
'strongStart' => '<strong>',
|
||||
'strongEnd' => '</strong>',
|
||||
]) .
|
||||
'</br>' .
|
||||
__(
|
||||
':divStart:image:hgroupStart:strongStartLe saviez-vous ?:strongEnd 100% des emballages cartons Le Gaulois sont déjà issus de cartons recyclés et certifiés FSC, garantissant une gestion responsable des forêts, et plus de 60% des barquettes de volaille Le Gaulois sont recyclables ou intégrant au moins 50% de matière recyclée.:hgroupEnd:divEnd',
|
||||
':divStart:image:hgroupStart:strongStartLe saviez-vous ?:strongEnd 100% des emballages cartons Le Gaulois sont déjà issus de :strongStartcartons recyclés et certifiés FSC:strongEnd, garantissant une gestion responsable des forêts, et :strongStartplus de 60% des barquettes:strongEnd de volaille Le Gaulois sont recyclables ou intégrant :strongStartau moins 50% de matière recyclée.:hgroupEnd:divEnd:strongEnd',
|
||||
[
|
||||
'image' =>
|
||||
'<img src="' .
|
||||
|
|
@ -190,6 +196,7 @@
|
|||
// Item 4
|
||||
$complexItem4 = new stdClass();
|
||||
$complexItem4->title = str(__('moins de plastique'))->upper();
|
||||
$complexItem4->text = str(__('minimiser notre empreinte carbone et agir sur le changement climatique'));
|
||||
$complexItem4->picto = 'resources/assets/images/commitments/pictograms/picto-plastic-decrease.svg';
|
||||
$complexItem4->picto_alt = __('Pictogramme d’un sac plastique avec l’estampille de recyclabilité');
|
||||
$complexItem4->picto_title = __('Pictogramme sur la diminution de plastique');
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@
|
|||
@section('bg-offset', true)
|
||||
|
||||
@section('content')
|
||||
<section id="home" class="overflow-hidden">
|
||||
<section class="overflow-hidden" id="home">
|
||||
{{-- HOT NEWS --}}
|
||||
<div id="hot-news" @class([
|
||||
'd-none position-fixed top-50 end-0 translate-middle-y bottom-left-shadow z-3',
|
||||
'd-xl-block' => !cache('hotNewsIsDisplayed'),
|
||||
])>
|
||||
<div class="line-border-small py-3 bg-white">
|
||||
<div class="line-border-small bg-white py-3">
|
||||
<div class="bg-primary position-absolute w-100 h-100 z-2 start-0 top-0 bg-opacity-50" id="hot-news-loader">
|
||||
<div class="position-absolute start-50 top-50 translate-middle">
|
||||
<div class="spinner-border" role="status">
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-close position-absolute start-0 top-0 pt-3 ms-2 pe-2 mt-2 bg-white opacity-100" id="close-hot-news"
|
||||
<button class="btn-close position-absolute start-0 top-0 ms-2 mt-2 bg-white pe-2 pt-3 opacity-100" id="close-hot-news"
|
||||
aria-label="Close"></button>
|
||||
@include('fo.partials.hot-news')
|
||||
</div>
|
||||
|
|
@ -31,19 +31,16 @@
|
|||
<div class="swiper swiper-main-slides overflow-visible" id="swiper-main-slides">
|
||||
<div class="swiper-wrapper w-fit">
|
||||
@foreach ($mainSlideModels as $mainSlideModel)
|
||||
<div class="swiper-slide h-auto pb-5 pb-md-0" style="background-color:{{ $mainSlideModel->color_block }}">
|
||||
<div class="swiper-slide pb-md-0 h-auto pb-5" style="background-color:{{ $mainSlideModel->color_block }}">
|
||||
<div class="swiper-background d-flex justify-content-center align-items-center">
|
||||
<img src="{{ asset($mainSlideModel->background) }}"
|
||||
title="{{ $mainSlideModel->background_title }}"
|
||||
<img src="{{ asset($mainSlideModel->background) }}" title="{{ $mainSlideModel->background_title }}"
|
||||
alt="{{ $mainSlideModel->background_alt }}">
|
||||
</div>
|
||||
<div
|
||||
class="card d-flex flex-column-reverse flex-sm-row align-items-center align-items-sm-start justify-content-center align-items-md-center flex-row border-0 bg-transparent">
|
||||
@if ($mainSlideModel->picture)
|
||||
<img class="card-picture img-fluid ms-md-0 ms-sm-2 ms-0"
|
||||
src="{{ asset($mainSlideModel->picture) }}"
|
||||
title="{{ $mainSlideModel->picture_title }}"
|
||||
alt="{{ $mainSlideModel->picture_alt }}">
|
||||
<img class="card-picture img-fluid ms-md-0 ms-sm-2 ms-0" src="{{ asset($mainSlideModel->picture) }}"
|
||||
title="{{ $mainSlideModel->picture_title }}" alt="{{ $mainSlideModel->picture_alt }}">
|
||||
@endif
|
||||
<div @class([
|
||||
'card-body position-relative p-0',
|
||||
|
|
@ -106,14 +103,13 @@
|
|||
<img src="{{ Vite::asset('resources/assets/images/common/arrow-brown.svg') }}"
|
||||
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
|
||||
</button>
|
||||
<img class="w-100 d-none d-xl-block"
|
||||
src="{{ Vite::asset('resources/assets/images/home/bg-slider-wood.png') }}"
|
||||
<img class="w-100 d-none d-xl-block" src="{{ Vite::asset('resources/assets/images/home/bg-slider-wood.png') }}"
|
||||
alt="{{ __('Footer imitation bois du slider') }}">
|
||||
</section>
|
||||
@endif
|
||||
{{-- HOT NEWS DESKTOP --}}
|
||||
<div class="position-relative d-block d-xl-none" id="hot-news-desktop">
|
||||
<div class="position-absolute start-0 wood-background w-100"></div>
|
||||
<div class="position-absolute wood-background w-100 start-0"></div>
|
||||
<div class="d-block d-xl-none hot-news-position position-relative bottom-left-shadow mx-auto">
|
||||
<div class="line-border-small bg-white">
|
||||
@include('fo.partials.hot-news')
|
||||
|
|
@ -165,11 +161,9 @@
|
|||
<div class="swiper-wrapper w-fit">
|
||||
@foreach ($demarcheSlideModels as $demarcheSlideModel)
|
||||
<div class="swiper-slide position-relative p-lg-5 pb-lg-0 h-auto overflow-hidden p-0">
|
||||
<div
|
||||
class="slide-background line-border-medium position-absolute start-50 translate-middle-x w-100">
|
||||
<div class="slide-background line-border-medium position-absolute start-50 translate-middle-x w-100">
|
||||
<img src="{{ Vite::asset('resources/assets/images/home/bg-demarche-slider.jpg') }}"
|
||||
title="{{ __('Image de fond du carrousel') }}"
|
||||
alt="{{ __('Paysage de champs') }}">
|
||||
title="{{ __('Image de fond du carrousel') }}" alt="{{ __('Paysage de champs') }}">
|
||||
</div>
|
||||
<div class="h-100 container">
|
||||
<div class="slide-card position-relative h-100">
|
||||
|
|
@ -181,8 +175,7 @@
|
|||
alt="#FIXME:alt de l'image de la démarche">
|
||||
</a>
|
||||
<div class="slide-content position-relative pt-lg-0 pt-2">
|
||||
<div
|
||||
class="line-border-medium bg-light position-absolute w-100 h-100 start-0 top-0">
|
||||
<div class="line-border-medium bg-light position-absolute w-100 h-100 start-0 top-0">
|
||||
</div>
|
||||
<div class="slide-content-texts position-relative z-1 p-lg-5 p-3">
|
||||
<h2 class="text-secondary fs-2">
|
||||
|
|
@ -216,14 +209,12 @@
|
|||
<button
|
||||
class="swiper-button swiper-button-prev-custom swiper-demarche-button-prev rounded-circle z-1 mx-3 border-0 bg-white">
|
||||
<img src="{{ Vite::asset('resources/assets/images/common/arrow-brown.svg') }}"
|
||||
title="{{ __('Navigation du slider (gauche)') }}"
|
||||
alt="{{ __('flèche vers la gauche') }}">
|
||||
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
|
||||
</button>
|
||||
<button
|
||||
class="swiper-button swiper-button-next-custom swiper-demarche-button-next rounded-circle z-1 mx-3 border-0 bg-white">
|
||||
<img src="{{ Vite::asset('resources/assets/images/common/arrow-brown.svg') }}"
|
||||
title="{{ __('Navigation du slider (droite)') }}"
|
||||
alt="{{ __('flèche vers la droite') }}">
|
||||
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -241,6 +232,7 @@
|
|||
'models' => $recipeModels,
|
||||
'btnRouteName' => route('fo.recipes.index'),
|
||||
'btnRouteTitle' => 'recettes',
|
||||
'hasPagination' => true,
|
||||
])
|
||||
@endif
|
||||
{{-- NEWS --}}
|
||||
|
|
@ -280,8 +272,7 @@
|
|||
<div class="d-md-none">
|
||||
@foreach ($newsModels->slice(1, 3) as $newsModel)
|
||||
<li>
|
||||
<a class="text-decoration-none"
|
||||
href="{{ route('fo.news.show', $newsModel->slug) }}"
|
||||
<a class="text-decoration-none" href="{{ route('fo.news.show', $newsModel->slug) }}"
|
||||
title="{{ __('Voir l\'article :name', ['name' => $newsModel->title]) }}">
|
||||
<p class="f-bakerie-rough mb-0">
|
||||
{{ now()->subDays(rand(1, 31))->format('d/m/Y') }}</p>
|
||||
|
|
@ -292,8 +283,7 @@
|
|||
</div>
|
||||
@foreach ($newsModels->slice(4, count($newsModels)) as $newsModel)
|
||||
<li>
|
||||
<a class="text-decoration-none"
|
||||
href="{{ route('fo.news.show', $newsModel->slug) }}"
|
||||
<a class="text-decoration-none" href="{{ route('fo.news.show', $newsModel->slug) }}"
|
||||
title="{{ __('Voir l\'article :name', ['name' => $newsModel->title]) }}">
|
||||
<p class="f-bakerie-rough mb-0">
|
||||
{{ now()->subDays(rand(1, 31))->format('d/m/Y') }}</p>
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
{{-- HEADER --}}
|
||||
@include('fo.layouts.header-banner')
|
||||
{{-- MAIN CONTENT --}}
|
||||
<section id="video-section" class="position-relative bg-light line-border-large overflow-hidden pt-5">
|
||||
<section class="position-relative bg-light line-border-large overflow-hidden pt-5" id="video-section">
|
||||
<div class="bg-white-wood-full">
|
||||
<div class="container">
|
||||
<div class="row mb-5 mt-4 align-items-center">
|
||||
@include('fo.pages.news.toggleButton')
|
||||
<div class="row mb-2 justify-content-center">
|
||||
<div class="row align-items-center mb-5 mt-4">
|
||||
{{-- @include('fo.pages.news.toggleButton') --}}
|
||||
<div class="row justify-content-center mb-2">
|
||||
<div class="col-12 col-md-10 col-lg-8 ck-content">
|
||||
{!! clean($staticPageModel->content) !!}
|
||||
</div>
|
||||
|
|
@ -21,22 +21,22 @@
|
|||
<div class="row">
|
||||
@php
|
||||
$data = [
|
||||
'legendModels' => $newsCategories ?? [],
|
||||
'legendImages' => false,
|
||||
'legendField' => 'title',
|
||||
'routeAjax' => 'fo.news.filtered',
|
||||
'contentViews' => $newsViews,
|
||||
'contentSwiper' => false,
|
||||
'legendModels' => $newsCategories ?? [],
|
||||
'legendImages' => false,
|
||||
'legendField' => 'title',
|
||||
'routeAjax' => 'fo.news.filtered',
|
||||
'contentViews' => $newsViews,
|
||||
'contentSwiper' => false,
|
||||
'legendFakeFirst' => __('Toutes les actus'),
|
||||
'texts' => [
|
||||
'helperNoItems' => __('Aucune actualités disponibles dans cette catégorie'),
|
||||
'texts' => [
|
||||
'helperNoItems' => __('Aucune actualités disponibles dans cette catégorie'),
|
||||
'helperAllItems' => __('Toutes les actualités ont été chargées'),
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<div class="filter-cards" data-json='@json($data)'></div>
|
||||
<div class="filter-cards" data-json='@json($data)'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -129,6 +129,24 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{-- Video Modal --}}
|
||||
<div class="modal fade translate-middle top-50 start-50" id="testimonial-video-modal" aria-labelledby="testimonialVideoModalLabel"
|
||||
aria-hidden="true" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button class="btn-close" data-bs-dismiss="modal" type="button" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="video-inlaid ratio ratio-16x9" type="youtube"
|
||||
href="https://www.youtube.com/embed/{{ $testimonialModels->first()->video_id }}"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">{{ __('Fermer') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
{{-- ADVANTAGES --}}
|
||||
<section class="joinus mb-3" id="recruitment-advantages">
|
||||
|
|
@ -167,7 +185,7 @@
|
|||
</section>
|
||||
{{-- NEWS CORPORATE --}}
|
||||
<section class="line-border-large bg-light py-5" id="recruitment-news-corporate">
|
||||
<div class="container-fluid pt-lg-0 pt-5">
|
||||
<div class="pt-lg-0 container pt-5">
|
||||
<div class="row w-100 justify-content-center mx-auto">
|
||||
<div class="col-12">
|
||||
<h2 class="h1 f-intro-head-h-base text-center">
|
||||
|
|
@ -183,7 +201,7 @@
|
|||
id="swiper-recruitment-news-corporates">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($newsCorporateModels as $newsCorporateModel)
|
||||
<div class="swiper-slide">
|
||||
<div class="swiper-slide h-auto">
|
||||
@include('fo.partials.news-corporate-card', [
|
||||
'newsCorporateModel' => $newsCorporateModel,
|
||||
])
|
||||
|
|
|
|||
|
|
@ -8,19 +8,20 @@
|
|||
--}}
|
||||
|
||||
<div class="breeding-card bottom-left-shadow position-relative card mb-5 border-0 bg-transparent">
|
||||
<div class="card-img-top line-border-medium img-wrapper bg-white p-2">
|
||||
<img class="w-100 line-border-medium" src="{{ asset($picture['src']) }}" title="{{ $picture['alt'] }}" alt="{{ $picture['title'] }}">
|
||||
</div>
|
||||
<div class="card-body position-absolute w-100 d-flex flex-column p-0">
|
||||
<div class="position-relative">
|
||||
<div class="line-border-medium text-zone pb-4 pt-3">
|
||||
<p class="text-uppercase fs-4 f-bourton-base px-4 pt-3 text-white">{{ $title }}</p>
|
||||
</div>
|
||||
<div class="position-absolute w-100 d-flex justify-content-center breeding-card-btn">
|
||||
<a class="btn btn-quint f-bourton-base" href="{{ $link }}"
|
||||
@if (!empty($linkNewTab)) target="_blank" @endif>{{ __('En savoir plus') }}</a>
|
||||
<a href="{{ $link }}" @if (!empty($linkNewTab)) target="_blank" @endif>
|
||||
<div class="card-img-top line-border-medium img-wrapper bg-white p-2">
|
||||
<img class="w-100 line-border-medium" src="{{ asset($picture['src']) }}" title="{{ $picture['alt'] }}"
|
||||
alt="{{ $picture['title'] }}">
|
||||
</div>
|
||||
<div class="card-body position-absolute w-100 d-flex flex-column p-0">
|
||||
<div class="position-relative">
|
||||
<div class="line-border-medium text-zone pb-4 pt-3">
|
||||
<p class="text-uppercase fs-4 f-bourton-base px-4 pt-3 text-white">{{ $title }}</p>
|
||||
</div>
|
||||
<div class="position-absolute w-100 d-flex justify-content-center breeding-card-btn">
|
||||
<div class="btn btn-quint f-bourton-base">{{ __('En savoir plus') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
<section id="commitments-banner-text-complex-items" class="position-relative w-100 py-5">
|
||||
<div class="position-absolute top-50 start-0 translate-middle-y overflow-hidden w-100 h-100">
|
||||
<img class="w-100" src="{{ Vite::asset($picture) }}"
|
||||
alt="{{ $picture_alt }}" title="{{ $picture_title }}">
|
||||
<section class="position-relative w-100 py-5" id="commitments-banner-text-complex-items">
|
||||
<div class="responsive-position top-50 translate-middle-y w-100 h-100 start-0 overflow-hidden">
|
||||
<img class="w-100" src="{{ Vite::asset($picture) }}" title="{{ $picture_title }}" alt="{{ $picture_alt }}">
|
||||
</div>
|
||||
<div class="container position-relative w-100 h-fit">
|
||||
<div class="position-relative w-100 container h-fit">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6">
|
||||
<h2 class="text-white">{{ $title }}</h2>
|
||||
<h2 class="banner-title">{{ $title }}</h2>
|
||||
</div>
|
||||
<div class="text-custom-placement col-12 col-md-6">
|
||||
<hgroup class="line-border-small bg-white p-4">
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<section id="commitments-complex-flex-items" class="position-relative">
|
||||
<section class="position-relative" id="commitments-complex-flex-items">
|
||||
@if (isset($title) && isset($picto))
|
||||
<div class="position-absolute start-50 translate-middle w-100 px-5 z-1">
|
||||
<div class="position-relative d-flex justify-content-center align-items-center w-fit mx-auto">
|
||||
<img class="title-image position-absolute start-0 top-50 translate-middle img-fluid z-1"
|
||||
src="{{ Vite::asset($picto) }}" alt="{{ $picto_alt }}" title="{{ $picto_title }}">
|
||||
<div class="bg-tertiary line-border-small w-fit ps-5 p-3">
|
||||
<h3 class="m-0">{{ $title }}</h3>
|
||||
<div class="position-absolute start-50 translate-middle w-100 z-1 px-5">
|
||||
<div class="position-relative d-flex justify-content-center align-items-center mx-auto w-fit">
|
||||
<img class="title-image position-absolute top-50 translate-middle img-fluid z-1 start-0" src="{{ Vite::asset($picto) }}"
|
||||
title="{{ $picto_title }}" alt="{{ $picto_alt }}">
|
||||
<div class="bg-tertiary line-border-small w-fit p-3 ps-5">
|
||||
<h3 class="m-0 text-center">{{ $title }}</h3>
|
||||
@if (isset($subtitle))
|
||||
<p class="f-bourton-base m-0">{{ $subtitle }}</p>
|
||||
@endif
|
||||
|
|
@ -14,15 +14,14 @@
|
|||
</div>
|
||||
@endif
|
||||
<div class="line-border-large bg-{{ $background_color }} pb-5">
|
||||
<div
|
||||
class="container d-flex flex-column flex-md-row justify-content-center justify-content-evenly align-items-start pt-5 pb-4">
|
||||
<div class="row justify-content-evenly align-items-start w-100 mx-auto mt-4 mt-lg-0">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-center justify-content-evenly align-items-start container pb-4 pt-5">
|
||||
<div class="row justify-content-evenly align-items-start w-100 mt-lg-0 mx-auto mt-4">
|
||||
@foreach ($collection as $item)
|
||||
<div class="col-6 col-lg-4 card border-0 bg-transparent mb-3">
|
||||
<div class="col-6 col-lg-4 card mb-3 border-0 bg-transparent">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 d-flex justify-content-center align-items-center">
|
||||
<img class="img-fluid" src="{{ Vite::asset($item->picto) }}"
|
||||
alt="{{ $item->picto_alt }}" title="{{ $item->picto_title }}">
|
||||
<img class="img-fluid" src="{{ Vite::asset($item->picto) }}" title="{{ $item->picto_title }}"
|
||||
alt="{{ $item->picto_alt }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="card-body text-center">
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
'picto_alt' => __('Pictogramme d\'une plante'),
|
||||
'picto_title' => __('Pousse d\'une plante au creux d\'une main'),
|
||||
'title' => __('respecter la terre'),
|
||||
'text' => __('être la grande marque alimentaire française'),
|
||||
'text' => __('minimiser notre empreinte carbone et agir sur le changement climatique'),
|
||||
'url' => route('fo.commitments.respect'),
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
<div class="swiper-slide">
|
||||
@include('fo.partials.breeding-card', [
|
||||
'picture' => [
|
||||
'src' => $item->picture,
|
||||
'src' => Vite::asset($item->picture),
|
||||
'alt' => $item->picture_alt,
|
||||
'title' => $item->picture_title,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@
|
|||
])
|
||||
@endif
|
||||
@if (isset($btnLabel) && !empty($btnLabel))
|
||||
<a href="{{ $btnLink }}" class="btn btn-{{ $btn_color }}"
|
||||
title="{{ __('Accéder à la page') }}"
|
||||
<a class="btn btn-{{ $btn_color }}" href="{{ $btnLink }}" title="{{ __('Accéder à la page') }}"
|
||||
aria-label="{{ __('Accéder à la page') }}">{{ $btnLabel }}</a>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -45,11 +44,10 @@
|
|||
'ratio ratio-16x9' => isset($video_id),
|
||||
])>
|
||||
@if (isset($picto) && !empty($picto))
|
||||
<img @class([
|
||||
<img src="{{ $picto }}" title="{{ $picto_title }}" alt="{{ $picto_alt }}" @class([
|
||||
'img-fluid position-absolute z-1',
|
||||
isset($reversed) && $reversed ? 'pictogram-reversed' : 'pictogram',
|
||||
]) src="{{ $picto }}" alt="{{ $picto_alt }}"
|
||||
title="{{ $picto_title }}">
|
||||
])>
|
||||
@endif
|
||||
<div class="bottom-left-shadow">
|
||||
<div @class([
|
||||
|
|
@ -69,30 +67,37 @@
|
|||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@if (isset($video_id) && \App\Rules\IsValidYoutubeId::validates($video_id))
|
||||
<div class="video-inlaid w-100 h-100" type="youtube"
|
||||
href="https://www.youtube.com/embed/{{ $video_id }}?autoplay=0&loop=1">
|
||||
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
|
||||
<strong class="text-underline text-bold text-normal text-danger">
|
||||
{{ __('cookie-notice.custom.youtube.warning') }}
|
||||
</strong>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="position-relative w-100 h-fit">
|
||||
@if (isset($video_id) && \App\Rules\IsValidYoutubeId::validates($video_id))
|
||||
@if (isset($isVideoModal) && isset($video_id) && \App\Rules\IsValidYoutubeId::validates($video_id))
|
||||
<div class="position-absolute z-1 w-100 h-100 start-0 top-0 bg-transparent" data-bs-toggle="modal"
|
||||
data-bs-target="#mecenat-chirurgie-video-modal" role="button"></div>
|
||||
@endif
|
||||
<div class="video-inlaid w-100 h-100" type="youtube"
|
||||
href="https://www.youtube.com/embed/{{ $video_id }}?autoplay=0&loop=1">
|
||||
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
|
||||
<strong class="text-underline text-bold text-normal text-danger">
|
||||
{{ __('cookie-notice.custom.youtube.warning') }}
|
||||
</strong>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if (!isset($video_id))
|
||||
<img class="img-fluid line-border-small w-100" src="{{ $picture }}"
|
||||
alt="{{ $picture_alt }}" title="{{ $picture_title }}">
|
||||
<img class="img-fluid line-border-small w-100" src="{{ $picture }}" title="{{ $picture_title }}"
|
||||
alt="{{ $picture_alt }}">
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@if (isset($card_title) && !empty($card_title))
|
||||
<div class="custom-card bottom-left-shadow w-fit mx-auto mt-5 mt-md-0 z-1">
|
||||
<img class="position-absolute z-2" src="{{ $card_picto }}" alt="{{ $card_picto_alt }}"
|
||||
title="{{ $card_picto_title }}">
|
||||
<p
|
||||
class="position-absolute start-0 text-light bg-secondary rotate-left h6 m-0 p-2 ps-5 z-1">
|
||||
<div class="custom-card bottom-left-shadow mt-md-0 z-1 mx-auto mt-5 w-fit">
|
||||
<img class="position-absolute z-2" src="{{ $card_picto }}" title="{{ $card_picto_title }}"
|
||||
alt="{{ $card_picto_alt }}">
|
||||
<p class="position-absolute text-light bg-secondary rotate-left h6 z-1 start-0 m-0 p-2 ps-5">
|
||||
{{ $card_sustitle }}</p>
|
||||
<div class="bg-tertiary line-border-small text-center p-4">
|
||||
<div class="bg-tertiary line-border-small p-4 text-center">
|
||||
<h2>{{ $card_title }}</h2>
|
||||
<p class="h6 m-0">{{ $card_subtitle }}</p>
|
||||
<p class="m-0">{{ $card_text }}</p>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
<section id="commitments-visual-with-cards" class="position-relative">
|
||||
<section class="position-relative" id="commitments-visual-with-cards">
|
||||
<div class="line-border-large bg-tertiary pb-5">
|
||||
<div
|
||||
class="container d-flex flex-column flex-md-row justify-content-center justify-content-evenly align-items-start pt-5 pb-4">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-center justify-content-evenly align-items-start container pb-4 pt-5">
|
||||
<div class="row justify-content-evenly align-items-start gx-5">
|
||||
<div class="col-12 mb-3">
|
||||
<h2>{{ $title }}</h2>
|
||||
</div>
|
||||
<div class="col-12 col-md-5">
|
||||
<div class="bottom-left-shadow mb-3">
|
||||
<img class="line-border-small bg-white p-3 img-fluid" src="{{ Vite::asset($picture) }}"
|
||||
alt="{{ $picture_alt }}" title="{{ $picture_title }}">
|
||||
<div class="line-border-small bg-white p-2">
|
||||
<img class="line-border-small img-fluid" src="{{ Vite::asset($picture) }}" title="{{ $picture_title }}"
|
||||
alt="{{ $picture_alt }}">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="bottom-left-shadow mb-3">
|
||||
<div class="line-border-small bg-white p-3">
|
||||
|
|
@ -18,20 +20,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-7">
|
||||
<div class="row w-100 mx-auto gx-5">
|
||||
<div class="row w-100 gx-5 mx-auto">
|
||||
<div class="col-12">
|
||||
{!! $subtext !!}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="row w-100 mx-auto">
|
||||
<div class="col-6">
|
||||
<div class="col-12 col-md-6">
|
||||
@foreach ($collection->slice(0, 2) as $item)
|
||||
<div class="custom-card bottom-left-shadow position-relative my-4">
|
||||
<div class="position-absolute d-flex justify-content-between align-items-center w-100 z-1">
|
||||
<p class="h6 m-0 p-2 text-white bg-secondary rotate-left">
|
||||
<p class="h6 bg-secondary rotate-left m-0 p-2 text-white">
|
||||
{{ $item->title }}</p>
|
||||
<img class="img-fluid" src="{{ Vite::asset($item->picto) }}"
|
||||
alt="{{ $item->picto_alt }}" title="{{ $item->picto_title }}">
|
||||
title="{{ $item->picto_title }}" alt="{{ $item->picto_alt }}">
|
||||
</div>
|
||||
<div class="line-border-small bg-white p-3 pt-5">
|
||||
{!! $item->text !!}
|
||||
|
|
@ -39,14 +41,14 @@
|
|||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="col-12 col-md-6">
|
||||
@foreach ($collection->slice(2, 2) as $item)
|
||||
<div class="custom-card bottom-left-shadow position-relative my-4">
|
||||
<div class="position-absolute d-flex justify-content-between align-items-center w-100 z-1">
|
||||
<p class="h6 m-0 p-2 text-white bg-secondary rotate-left">
|
||||
<p class="h6 bg-secondary rotate-left m-0 p-2 text-white">
|
||||
{{ $item->title }}</p>
|
||||
<img class="img-fluid" src="{{ Vite::asset($item->picto) }}"
|
||||
alt="{{ $item->picto_alt }}" title="{{ $item->picto_title }}">
|
||||
title="{{ $item->picto_title }}" alt="{{ $item->picto_alt }}">
|
||||
</div>
|
||||
<div class="line-border-small bg-white p-3 pt-5">
|
||||
{!! $item->text !!}
|
||||
|
|
@ -56,13 +58,13 @@
|
|||
</div>
|
||||
<div class="col-12">
|
||||
<div class="custom-card bottom-left-shadow position-relative">
|
||||
<div class="position-absolute w-fit z-1">
|
||||
<p class="h6 m-0 p-2 text-white bg-secondary rotate-left">
|
||||
<div class="position-absolute z-1 w-fit">
|
||||
<p class="h6 bg-secondary rotate-left m-0 p-2 text-white">
|
||||
{{ $collection->last()->title }}</p>
|
||||
</div>
|
||||
<div class="line-border-small bg-white d-flex justify-content-between align-items-center p-3">
|
||||
<div class="line-border-small d-flex justify-content-between align-items-center bg-white p-3">
|
||||
<img class="img-fluid" src="{{ Vite::asset($collection->last()->picto) }}"
|
||||
alt="{{ $collection->last()->picto_alt }}" title="{{ $collection->last()->picto_title }}">
|
||||
title="{{ $collection->last()->picto_title }}" alt="{{ $collection->last()->picto_alt }}">
|
||||
<div class="ms-2">
|
||||
{!! $collection->last()->text !!}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
alt="{{ $hotNewsSettings->value['picture_alt'] }}"
|
||||
title="{{ $hotNewsSettings->value['picture_title'] }}">
|
||||
<div class="f-bourton-base bg-danger text-bg-danger px-2 py-1">
|
||||
<span>@money($discountsTotal * 100)</span>
|
||||
<span>@money($discountsTotal)</span>
|
||||
{{ __(' d\'économie') }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,27 +4,28 @@
|
|||
$newsCorporateModel || New corporate model. || Model || REQUIRED ||
|
||||
--}}
|
||||
|
||||
<div class="news-card bottom-left-shadow card h-lg-100 border-0 bg-transparent w-100 w-lg-75 mx-0 mx-lg-auto mt-lg-0 mt-5">
|
||||
<div class="line-border-small h-100 bg-white">
|
||||
<div class="card-img-top position-relative mb-4">
|
||||
<img class="w-100 line-border-small"
|
||||
src="{{ asset($newsCorporateModel->picture) }}"
|
||||
title="{{ $newsCorporateModel->picture_alt }}"
|
||||
alt="{{ $newsCorporateModel->picture_title }}">
|
||||
<div @class(['position-absolute tag rotate-left', 'd-none' => $newsCorporateModel->url ? false : true])>
|
||||
<a href="{{ $newsCorporateModel->url ?? '#'}}"
|
||||
title="{{ __('Accéder à l\'article sur Linkedin') }}"
|
||||
target="_blank"
|
||||
class="text-decoration-none text-uppercase text-bg-quad f-bourton-base fs-5 px-2 py-1">
|
||||
{{ __('LINKEDIN') }}
|
||||
</a>
|
||||
<div class="news-card bottom-left-shadow card h-lg-100 w-100 mt-lg-0 mx-0 mt-5 border-0 bg-transparent">
|
||||
<a class="text-decoration-none h-100" href="{{ $newsCorporateModel->url ?? '#' }}" title="{{ __('Accéder à l\'article sur Linkedin') }}"
|
||||
target="_blank">
|
||||
<div class="line-border-small h-100 bg-white">
|
||||
<div class="card-img-top position-relative mb-4">
|
||||
<img class="w-100 line-border-small" src="{{ asset($newsCorporateModel->picture) }}"
|
||||
title="{{ $newsCorporateModel->picture_alt }}" alt="{{ $newsCorporateModel->picture_title }}">
|
||||
<div @class([
|
||||
'position-absolute tag rotate-left',
|
||||
'd-none' => $newsCorporateModel->url ? false : true,
|
||||
])>
|
||||
<div class="text-decoration-none text-uppercase text-bg-quad f-bourton-base fs-5 px-2 py-1">
|
||||
{{ __('LINKEDIN') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<h2 class="text-uppercase fs-4 f-bourton-base">
|
||||
{{ $newsCorporateModel->title }}
|
||||
</h2>
|
||||
<p class="fs-5">{{ str($newsCorporateModel->content)->limit(300) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<h2 class="text-uppercase fs-4 f-bourton-base">
|
||||
{{ $newsCorporateModel->title }}
|
||||
</h2>
|
||||
<p class="fs-5">{{ $newsCorporateModel->content }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<div class="news-small-card bottom-left-shadow border-0 bg-transparent">
|
||||
<a class="text-decoration-none" href="{{ $offerModel->link }}" target="_blank"
|
||||
title="{{ __('Accéder à l\'offre : :name', ['name' => $offerModel->title]) }}">
|
||||
<div class="line-border-small bg-white p-md-3">
|
||||
<div class="row w-100 mx-auto align-items-center">
|
||||
<div class="offer-small-card bottom-left-shadow h-100 border-0 bg-transparent">
|
||||
<a class="text-decoration-none" href="{{ $offerModel->link }}"
|
||||
title="{{ __('Accéder à l\'offre : :name', ['name' => $offerModel->title]) }}" target="_blank">
|
||||
<div class="line-border-small p-md-3 h-100 d-flex flex-column bg-white">
|
||||
<div class="row w-100 align-items-center mx-auto">
|
||||
<div class="col-12 d-flex flex-column flex-md-row justify-content-center align-items-center p-0">
|
||||
<img class="img-fluid" src="{{ $offerModel->picture }}" title="{{ $offerModel->picture_title }}"
|
||||
alt="{{ $offerModel->picture_alt }}">
|
||||
<div
|
||||
class="d-flex flex-column justify-content-start justify-content-md-center align-items-start w-100 mb-2 mt-3 m-md-0 ms-md-2 px-3 px-md-0">
|
||||
class="d-flex flex-column justify-content-start justify-content-md-center align-items-start w-100 m-md-0 ms-md-2 px-md-0 mb-2 mt-3 px-3">
|
||||
<h4>{{ $offerModel->title }}</h4>
|
||||
<p class="mb-0">
|
||||
{{ Str::limit($offerModel->description, 180) }}
|
||||
|
|
@ -17,14 +17,16 @@
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 d-flex flex-wrap p-3 pt-0 p-md-0 mt-md-1">
|
||||
<div class="bg-quad text-uppercase f-bourton-base text-white fs-5 mt-2 me-3 px-2 py-1">
|
||||
</div>
|
||||
<div class="row w-100 align-items-center flex-fill mx-auto">
|
||||
<div class="col-12 d-flex p-md-0 mt-md-1 align-items-center flex-wrap p-3 pt-0">
|
||||
<div class="bg-quad text-uppercase f-bourton-base fs-5 me-3 mt-2 px-2 py-1 text-white">
|
||||
{{ $offerModel->contract }}
|
||||
</div>
|
||||
<div class="bg-secondary text-uppercase f-bourton-base text-white fs-5 mt-2 me-3 px-2 py-1">
|
||||
<div class="bg-secondary text-uppercase f-bourton-base fs-5 me-3 mt-2 px-2 py-1 text-white">
|
||||
{{ $offerModel->location }}
|
||||
</div>
|
||||
<div class="bg-tertiary text-uppercase f-bourton-base fs-5 mt-2 me-3 px-2 py-1">
|
||||
<div class="bg-tertiary text-uppercase f-bourton-base fs-5 me-3 mt-2 px-2 py-1">
|
||||
{{ $offerModel->function }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<div class="position-relative product-card bottom-left-shadow mt-3 py-3">
|
||||
<div class="position-relative product-card bottom-left-shadow h-100 mt-5 py-3">
|
||||
<div class="line-border-medium bg-tertiary position-absolute w-100 h-75 left-0 start-0"></div>
|
||||
<div class="position-relative" title="{{ __('Accéder au produit : :name', ['name' => $model->label]) }}">
|
||||
<div class="h-75 position-relative" title="{{ __('Accéder au produit : :name', ['name' => $model->label]) }}">
|
||||
<a class="d-flex justify-content-center text-decoration-none pb-5" href="{{ route('fo.products.show', $model->slug) }}">
|
||||
<img src="{{ asset($model->packaging) }}" title="{{ $model->packaging_title }}" alt="{{ $model->packaging_alt }}"
|
||||
@class([
|
||||
|
|
@ -23,10 +23,9 @@
|
|||
</div>
|
||||
{{-- BOTTOM PART --}}
|
||||
<div class="position-relative">
|
||||
<div class="line-border-medium position-relative d-flex flex-column align-items-center product-card-bottom-part bg-white pb-3">
|
||||
<p class="text-uppercase f-bourton-base fs-4 my-4 px-4 text-center">
|
||||
{{ $model->label }}
|
||||
</p>
|
||||
<div
|
||||
class="line-border-medium position-relative d-flex flex-column align-items-center justify-content-center product-card-bottom-part bg-white pb-3">
|
||||
<p class="text-uppercase f-bourton-base fs-4 my-4 px-4 text-center">{{ $model->label }}</p>
|
||||
</div>
|
||||
<div class="position-absolute w-100 d-flex justify-content-center bottom-0">
|
||||
<a class="btn btn-secondary f-bourton-base product-card-view-more w-fit" href="{{ route('fo.products.show', $model->slug) }}"
|
||||
|
|
|
|||
|
|
@ -1,49 +1,51 @@
|
|||
<div class="recipe-card bottom-left-shadow h-100">
|
||||
<div class="line-border-medium h-100 bg-white">
|
||||
<div class="position-relative d-flex justify-content-center">
|
||||
<a class="text-decoration-none" href="{{ route('fo.recipes.show', $model->slug) }}"
|
||||
title="{{ __('Accéder à la recette : :title', ['title' => $model->title]) }}">
|
||||
<a class="text-decoration-none" href="{{ route('fo.recipes.show', $model->slug) }}"
|
||||
title="{{ __('Accéder à la recette : :title', ['title' => $model->title]) }}">
|
||||
<div class="line-border-medium h-100 bg-white">
|
||||
<div class="position-relative d-flex justify-content-center">
|
||||
|
||||
<img class="w-100 line-border-medium" src="{{ asset($model->picture) }}" title="{{ $model->picture_title }}"
|
||||
alt="{{ $model->picture_alt }}" />
|
||||
</a>
|
||||
{{-- FIXME: change packaging by the first product packaging
|
||||
|
||||
{{-- FIXME: change packaging by the first product packaging
|
||||
<img class="w-25 position-absolute recipe-card-product rotate-left z-1 bottom-0" src="{{ $model->products[0]->packaging }}"
|
||||
title="{{ $model->products[0]->packaging_title }}" alt="{{ $model->products[0]->packaging_alt }}" /> --}}
|
||||
<x-fo.btn-club-favorite :model="$model" />
|
||||
</div>
|
||||
<div class="recipe-card-bottom-part d-flex flex-column align-items-center px-3 pt-5">
|
||||
<div style="min-height: 6.2rem; display: flex; align-items: center;">
|
||||
<p class="text-uppercase fs-4 f-bourton-base text-center">
|
||||
{{ $model->title }}
|
||||
</p>
|
||||
<x-fo.btn-club-favorite :model="$model" />
|
||||
</div>
|
||||
{{-- TIMES (COOKING & PREPARATION) & DIFFICULTY --}}
|
||||
<div class="d-flex justify-content-around w-100">
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/clock.svg') }}"
|
||||
title="{{ __('Icône du temps de préparation') }}" alt="{{ __('Horloge') }}" />
|
||||
{{ $model->convertTime($model->preparation_time) }}
|
||||
</p>
|
||||
@if ($model->cooking_time)
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/cooking-pot.svg') }}"
|
||||
title="{{ __('Icône du temps de cuisson') }}" alt="{{ __('Soupière') }}" />
|
||||
{{ $model->convertTime($model->cooking_time) }}
|
||||
<div class="recipe-card-bottom-part d-flex flex-column align-items-center px-3 pt-5">
|
||||
<div style="min-height: 6.2rem; display: flex; align-items: center;">
|
||||
<p class="text-uppercase fs-4 f-bourton-base text-center">
|
||||
{{ $model->title }}
|
||||
</p>
|
||||
@endif
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/toque.svg') }}" title="{{ __('Icône de difficulté') }}"
|
||||
alt="{{ __('Toque') }}" />
|
||||
{{ $model->difficulty->label() }}
|
||||
</p>
|
||||
</div>
|
||||
{{-- TIMES (COOKING & PREPARATION) & DIFFICULTY --}}
|
||||
<div class="d-flex justify-content-around w-100">
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/clock.svg') }}"
|
||||
title="{{ __('Icône du temps de préparation') }}" alt="{{ __('Horloge') }}" />
|
||||
{{ $model->convertTime($model->preparation_time) }}
|
||||
</p>
|
||||
@if ($model->cooking_time)
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/cooking-pot.svg') }}"
|
||||
title="{{ __('Icône du temps de cuisson') }}" alt="{{ __('Soupière') }}" />
|
||||
{{ $model->convertTime($model->cooking_time) }}
|
||||
</p>
|
||||
@endif
|
||||
<p class="text-uppercase fs-5 f-bourton-base">
|
||||
<img src="{{ Vite::asset('resources/assets/images/recipes/toque.svg') }}" title="{{ __('Icône de difficulté') }}"
|
||||
alt="{{ __('Toque') }}" />
|
||||
{{ $model->difficulty->label() }}
|
||||
</p>
|
||||
</div>
|
||||
{{-- SUBMEAT & CUNSUMPTION MOMENT --}}
|
||||
@include('fo.partials.recipe-badges', [
|
||||
'model' => $model,
|
||||
'classWrapper' => 'recipe-card-badges-wrapper d-flex w-100 justify-content-center flex-wrap pb-3',
|
||||
'class' =>
|
||||
'badge recipe-tag text-bg-tertiary text-secondary text-uppercase f-catamaran fw-normal mx-md-3 mx-1 mb-2 px-3',
|
||||
])
|
||||
</div>
|
||||
{{-- SUBMEAT & CUNSUMPTION MOMENT --}}
|
||||
@include('fo.partials.recipe-badges', [
|
||||
'model' => $model,
|
||||
'classWrapper' => 'recipe-card-badges-wrapper d-flex w-100 justify-content-center flex-wrap pb-3',
|
||||
'class' =>
|
||||
'badge recipe-tag text-bg-tertiary text-secondary text-uppercase f-catamaran fw-normal mx-md-3 mx-1 mb-2 px-3',
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
<div class="testimonial-card bottom-left-shadow h-100 w-lg-75 ms-lg-auto">
|
||||
<div class="position-relative d-flex justify-content-center testimonial-img-wrapper">
|
||||
<div class="line-border-small w-fit bg-white p-2">
|
||||
@if (!empty($model->video_id))
|
||||
<a class="video-link" data-bs-toggle="modal" data-bs-target="#testimonial-video-modal"
|
||||
data-video-link="https://www.youtube.com/embed/{{ $model->video_id }}">
|
||||
<i class="fa-solid fa-xl fa-play position-absolute z-1 rounded-circle translate-middle top-50 start-50 bg-white p-3"></i>
|
||||
@endif
|
||||
<img class="w-100 line-border-medium testimonial-img" src="{{ asset($model->picture) }}" title="{{ $model->picture_title }}"
|
||||
alt="{{ $model->picture_alt }}" />
|
||||
@if (!empty($model->video_id))
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="line-border-medium position-relative d-flex flex-column testimonial-card-bottom-part px-lg-5 px-lg-4 pb-lg-4 bg-light px-3 pt-4">
|
||||
class="line-border-medium position-relative d-flex flex-column testimonial-card-bottom-part px-lg-5 px-lg-4 pb-lg-4 bg-light h-lg-100 px-3 pt-4">
|
||||
<p class="text-uppercase fs-3 f-bourton-base mb-1">
|
||||
{{ $model->identity }}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script @if (isset($nonce)) nonce="{{ $nonce }}" @endif>
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
if (!window.__SYSTEM) {
|
||||
window.__SYSTEM = {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{-- blade-formatter-disable --}}
|
||||
@include('modules.script-constants')
|
||||
<script @if (isset($nonce)) nonce="{{ $nonce }}" @endif>
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
if (!window.__SYSTEM._routes) {
|
||||
window.__SYSTEM._routes = {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ Breadcrumbs::for('fo.recipes.search.submeat', function (Generator $trail) {
|
|||
// * COMMITMENTS
|
||||
Breadcrumbs::for('fo.commitments.index', function (Generator $trail) {
|
||||
$trail->parent('fo.home.show');
|
||||
$trail->push(Str::of(trans('nos engagements'))->ucfirst(), route('fo.commitments.index'));
|
||||
// FIXME: Le lien ci-dessous doit etre .index après la MEP.
|
||||
$trail->push(Str::of(trans('nos engagements'))->ucfirst(), route('fo.commitments.brand'));
|
||||
});
|
||||
Breadcrumbs::for('fo.commitments.brand', function (Generator $trail) {
|
||||
$trail->parent('fo.commitments.index');
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ Route::middleware(['throttle:web', 'admin-secure'])->prefix('bo')->name('bo.')->
|
|||
'verify' => false,
|
||||
]
|
||||
);
|
||||
Route::get('/login-error', function () {
|
||||
return view('bo.pages.login-error');
|
||||
})->name('login-error');
|
||||
});
|
||||
Route::middleware('auth:backend')->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue