Compare commits

..

91 commits

Author SHA1 Message Date
Vincent BRIDIER
314ef2dff7 Fix vite config for CI 2023-11-08 09:07:00 +00:00
Alexis Gousseau
f80f43a0a0 fix phpcs 2023-11-07 13:12:08 +01:00
Alexis Gousseau
6dc813e366 update social media icons 2023-11-07 13:06:17 +01:00
Alexis Gousseau
fc7dad207e add pagination on news 2023-11-07 13:06:04 +01:00
Alexis Gousseau
bdbbb9ff9a add news.index + news.show pages 2023-11-06 16:05:48 +01:00
Alexis Gousseau
705aa7c522 lot of fix (translations, docblocks, saveQuietly seeder) 2023-11-06 12:57:17 +01:00
Alexis Gousseau
3c63d85bd9 update bo joinus: remove index page and redirect to the edit 2023-11-06 11:19:08 +01:00
Alexis Gousseau
2648256177 update bo conviction: remove index page and redirect to the edit 2023-11-06 11:13:14 +01:00
Alexis Gousseau
5f90384be4 update bo explorer: remove index page and redirect to the edit 2023-11-06 11:04:33 +01:00
Alexis Gousseau
35f6d98dbc update bo homepage: remove index page and redirect to the edit 2023-11-06 11:03:49 +01:00
Alexis Gousseau
480482f5b2 update contact pdf validation 2023-11-06 09:28:50 +01:00
Alexis Gousseau
7bf122def5 fix joinus->video_id 2023-11-06 09:28:34 +01:00
Alexis Gousseau
f374271268 fix/conformity 2023-11-02 17:17:54 +01:00
Sebastien Hattry
7e9292e27e Fix title display 2023-11-02 11:26:10 +01:00
Sebastien Hattry
54b3d22d40 About page responsive 2/2 2023-11-02 10:52:56 +01:00
Alexis Gousseau
480d6394b4 WIP: add joinus page 2023-11-02 09:36:22 +01:00
Noah Lancien
f693e2a195 Added 'nos-convictions page 2023-11-02 09:34:29 +01:00
Sebastien Hattry
58518d0238 About page responsive 1/2 2023-10-31 17:26:08 +01:00
Sebastien Hattry
acd7e13c81 fix bug 2023-10-31 11:03:12 +01:00
Sebastien Hattry
404b022a17 Add about us page 1/2 2023-10-31 10:47:58 +01:00
Noah Lancien
a65d855acc Added products.show page 2023-10-30 17:31:15 +01:00
Alexis Gousseau
aba83a5c91 add ranges.show page 2023-10-30 16:51:12 +01:00
Alexis Gousseau
9481b4ca70 add ranges.index page 2023-10-30 15:39:31 +01:00
Alexis Gousseau
45ff265caf fix contact page 2023-10-30 12:14:43 +01:00
Noah Lancien
87b2ca2368 Fixed 404 and 503 pages 2023-10-27 16:52:28 +02:00
Noah Lancien
50c743f728 Fixed 404 and 503 pages 2023-10-27 16:43:37 +02:00
Noah Lancien
91094d9120 Added 'Explorateur & Gastronome' page 2023-10-27 16:29:31 +02:00
Jérémy Munsch
3d959fd37c
Upgrade using base project bump 2023-10-27 15:13:51 +02:00
Alexis Gousseau
0f4fe5eaac add contact page 2023-10-27 11:41:57 +02:00
Alexis Gousseau
58111ca5dd add homepage 2023-10-26 10:32:22 +02:00
Sebastien Hattry
97817caaaa Add Bootstrap font-size 2023-10-25 10:52:54 +02:00
Nicolas Demangeat
066fd0c8b3 fix blade trad 2023-10-24 17:05:45 +02:00
Sebastien Hattry
97dc1acf2a Change cookies behaviour 2023-10-24 17:04:52 +02:00
Sebastien Hattry
608803bd0c Add StaticPage controller instead of legals and policies 2023-10-24 16:36:31 +02:00
Sebastien Hattry
bd5be3fce1 Add legals and polices pages 2023-10-24 16:16:35 +02:00
Sebastien Hattry
8668c6a38c Add CSP execptions rules for cookies 2023-10-24 16:11:24 +02:00
Nicolas Demangeat
6e01470b5c add crud testimonial 2023-10-24 15:15:55 +02:00
Sebastien Hattry
f9a7728375 Add cookies notice settings in env.example 2023-10-24 12:18:22 +02:00
Sebastien Hattry
4d5dc72b11 issue-30 - Add cookie notice 2023-10-24 12:12:23 +02:00
Nicolas Demangeat
b01c6cc577 add crud join us page 2023-10-24 11:53:24 +02:00
Nicolas Demangeat
d97071b740 add commitments to explorer page selection 2023-10-24 10:08:32 +02:00
Noah Lancien
a17953deb1 Added commitments select in product CRUD 2023-10-23 16:49:40 +02:00
nicolas.demangeat
6e433628b5 Merge branch 'crud-convictionpage' into '2.0.0'
added conviction page

See merge request ldc-web/projets/agis!11
2023-10-23 14:33:16 +00:00
Nicolas Demangeat
3f15d48355 added conviction page 2023-10-23 16:29:49 +02:00
Noah Lancien
d61f05640d Added Product CRUD 2023-10-23 12:24:37 +02:00
nicolas.demangeat
3e64820fb8 Merge branch 'crud-explorerpage' into '2.0.0'
Crud explorerpage

See merge request ldc-web/projets/agis!10
2023-10-23 10:18:11 +00:00
Nicolas Demangeat
21d0ec429f added explorer page 2023-10-23 12:14:52 +02:00
Jérémy Munsch
ca54e892b5
Closes #3
inputs ok
2023-10-23 11:41:52 +02:00
Jérémy Munsch
608852e80a
inputs ok 2023-10-23 11:32:13 +02:00
Jérémy Munsch
425a7b223d
Fix footer layout for desktop 2023-10-23 11:04:04 +02:00
nicolas.demangeat
6ceb64a50c Merge branch 'crud-homepage' into '2.0.0'
added homepage

See merge request ldc-web/projets/agis!9
2023-10-23 08:54:49 +00:00
Nicolas Demangeat
6d6729285b fix conflicts 2023-10-23 10:52:00 +02:00
Jérémy Munsch
4cc8134e96
footer desktop ok 2023-10-23 10:51:39 +02:00
Nicolas Demangeat
e1994588e1 added homepage 2023-10-23 10:42:57 +02:00
Jérémy Munsch
5220fc130f
footer mobile ok 2023-10-23 10:09:45 +02:00
Noah Lancien
70e05dd6fa Fixed duplicated imports and phpcs 2023-10-23 07:15:30 +00:00
Noah Lancien
3ceaceacb6 Resolved conflicts on crud-stamps 2023-10-20 17:18:46 +02:00
Noah Lancien
abc6dd8484 Added News CRUD 2023-10-20 15:16:13 +00:00
Noah Lancien
b63450f905 Added stamps CRUD 2023-10-20 17:11:08 +02:00
nicolas.demangeat
34235baa16 Merge branch 'crud-commitments' into '2.0.0'
added commitments crud

See merge request ldc-web/projets/agis!8
2023-10-20 15:09:24 +00:00
Nicolas Demangeat
1242d4893f fix breadcrumbs 2023-10-20 17:06:59 +02:00
Nicolas Demangeat
e7ce6aef02 fix conflicts 2023-10-20 17:04:02 +02:00
Nicolas Demangeat
7d689d30fb added commitments crud 2023-10-20 16:56:44 +02:00
Noah Lancien
219eba96ec Resolved conflicts in crud-news 2023-10-20 16:23:04 +02:00
Noah Lancien
0d7bdd5901 Merge branch 'crud-seasonalsections' into 2.0.0 2023-10-20 16:17:19 +02:00
Noah Lancien
3712af4419 Added seasonal sections CRUD 2023-10-20 16:16:36 +02:00
Jérémy Munsch
fe494a24cf
Add run vite config with ssl 2023-10-20 15:01:42 +02:00
Noah Lancien
f3a7994154 Added News CRUD 2023-10-20 14:35:57 +02:00
Vincent BRIDIER
ff10196da7 Merge branch 'crud-ranges' into '2.0.0'
Added ranges CRUD + missing HasPicture Trait

See merge request ldc-web/projets/agis!6
2023-10-20 10:42:53 +00:00
noah.lancien
3343e18a11 Added ranges CRUD + missing HasPicture Trait 2023-10-20 10:42:53 +00:00
Jérémy Munsch
ed92ed2d94
Fix BS btn colors 2023-10-20 12:04:18 +02:00
Jérémy Munsch
f581a25ba7
Theme preparation TEST 2023-10-20 11:58:45 +02:00
Jérémy Munsch
c2b5daa67c
npm audit fix 2023-10-20 11:58:45 +02:00
Vincent BRIDIER
2a46a25165 Merge branch 'issue-11-static-page-crud' into '2.0.0'
Issue 11 static page crud

See merge request ldc-web/projets/agis!5
2023-10-20 08:53:04 +00:00
Noah Lancien
e346e65d7d Fixed static_pages translations 2023-10-20 10:45:11 +02:00
Noah Lancien
a807c9656c Lock content modificiation for pages that don't need content 2023-10-20 10:40:44 +02:00
Noah Lancien
ba73f40554 Added static pages crud from base project 2023-10-20 10:29:38 +02:00
Noah Lancien
037b859066 Fixed commands name 2023-10-20 10:27:33 +02:00
Vincent BRIDIER
0e4d84cc6f Merge branch 'issue-5-seeders-factories' into '2.0.0'
Issue 5 seeders factories

See merge request ldc-web/projets/agis!4
2023-10-20 07:39:18 +00:00
noah.lancien
57e84ab247 Close #5 seeders factories 2023-10-20 07:39:18 +00:00
Jérémy Munsch
656562afe5
Peacock color 2023-10-19 14:26:51 +02:00
Jérémy Munsch
76114a0d59
composer update 2023-10-19 14:24:11 +02:00
Jérémy Munsch
5f16a9e77f
Add missing bootstrap elements 2023-10-19 14:22:48 +02:00
Vincent BRIDIER
78931c7a46 Merge branch 'last-base-project-updates' into '2.0.0'
Updated with the last version of base project

See merge request ldc-web/projets/agis!3
2023-10-19 09:22:22 +00:00
Vincent BRIDIER
96ed23b5c9 Merge branch 'issue-2-migrations' into '2.0.0'
Issue 2 migrations

See merge request ldc-web/projets/agis!2
2023-10-19 09:21:36 +00:00
noah.lancien
f8eb6f481e Issue 2 migrations Close #2 2023-10-19 09:21:36 +00:00
Noah Lancien
1564eb8bc3 Updated with the last version of base project 2023-10-18 16:25:43 +02:00
Vincent BRIDIER
f47d3f6fd1
Update composer.json + Fix PSR4 2023-10-18 12:22:36 +02:00
Noah Lancien
338715d9eb Updated bo footer and README 2023-10-17 16:02:25 +02:00
Noah Lancien
b25444263a Init laravel 10 2023-10-17 14:58:21 +02:00
Noah Lancien
dc41c9aa82 Reset project 2023-10-17 14:52:32 +02:00
62 changed files with 1766 additions and 2928 deletions

View file

@ -3,6 +3,7 @@ APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
ASSET_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
@ -22,6 +23,12 @@ QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
@ -30,7 +37,26 @@ MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
MAIL_CONTACTFORM_RECEIVER=
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=
@ -43,6 +69,3 @@ MATOMO_SITE_ID=
GOOGLE_RECAPTCHA_PUBLIC=
GOOGLE_RECAPTCHA_PRIVATE=
GOOGLE_RECAPTCHA_VERSION=
# Admin secure
LDC_WEB_API_KEY=

View file

@ -1,5 +0,0 @@
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
COPY --chown=www-data:www-data . /app/srcs
USER root
RUN chmod -R 755 /app/srcs/storage
USER www-data

View file

@ -1,7 +1 @@
# Agis
## CRON
Put every min in PROD :
```
php artisan schedule:run
```

View file

@ -139,7 +139,7 @@ class CommitmentController extends Controller
{
$commitment->products()->detach();
if ($commitment->explorerpage()->count() === 0) {
if ($commitment->explorerpage()->count() > 3) {
if ($commitment->deleteOrFail()) {
return redirect()->route('bo.commitments.index')
->with('success', __('crud.messages.has_been_deleted', [

View file

@ -24,7 +24,6 @@ class NewsController extends Controller
/** @var \App\Models\News $newsModels */
$newsModels = News::query()->where('published', true)->orderBy('publish_at', 'desc')->paginate(12);
return view('fo.pages.news.index', \compact('staticPageModel', 'newsModels'));
}

View file

@ -3,7 +3,6 @@
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Lib\Helpers\CollectionHelper;
use App\Models\Product;
class ProductController extends Controller
@ -11,35 +10,16 @@ class ProductController extends Controller
/**
* Display the product page.
*
* @param string $slug
* @param \App\Models\Product $product
* @return \Illuminate\Contracts\View\View
*/
public function show(string $slug): \Illuminate\Contracts\View\View
public function show(Product $product): \Illuminate\Contracts\View\View
{
$productModel = Product::query()->where('slug', $slug)->firstOrFail();
$otherProductModels = $productModel->range->products()
->where('id', '!=', $productModel->id)
$otherProductModels = $product->range->products()
->where('id', '!=', $product->id)
->where('published', true)
->inRandomOrder()
->get();
return view('fo.pages.products.show', compact('productModel', 'otherProductModels'));
}
/**
* Get filtered products.
*
* @return \Illuminate\Http\JsonResponse
*/
public function productsFiltered(): \Illuminate\Http\JsonResponse
{
$productModels = Product::query()
->where('published', true)
->where('range_id', request()->range_id)
->orderBy('order', 'asc')
->get();
$productModels = CollectionHelper::paginateManually($productModels, 12, request()->page);
return response()->json($productModels);
return view('fo.pages.products.show', compact('product', 'otherProductModels'));
}
}

View file

@ -4,7 +4,6 @@ namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Lib\Helpers\CollectionHelper;
use App\Models\Product;
use App\Models\Range;
use App\Models\StaticPage;
@ -18,12 +17,12 @@ class RangeController extends Controller
*/
public function index(): \Illuminate\Contracts\View\View
{
/** @var \App\Models\Range $rangeModels */
$rangeModels = Range::query()->where('published', true)->orderBy('order')->get();
/** @var \App\Models\StaticPage $staticPageModel */
$staticPageModel = StaticPage::query()->where('type', StaticPageType::ranges)->firstOrFail();
/** @var \App\Models\Range $rangeModels */
$rangeModels = Range::query()->where('published', true)->orderBy('order')->paginate(12);
return view('fo.pages.ranges.index', compact('rangeModels', 'staticPageModel'));
}
@ -39,27 +38,8 @@ class RangeController extends Controller
$rangeModel = Range::query()->where('published', true)->where('slug', $slug)->firstOrFail();
/** @var \App\Models\Product $productModels */
$productModels = Product::query()
->where('range_id', $rangeModel->id)
->where('published', true)
->orderBy('order')
->paginate(12);
$productModels = Product::query()->where('range_id', $rangeModel->id)->where('published', true)->get();
return view('fo.pages.ranges.show', compact('rangeModel', 'productModels'));
}
/**
* Get filtered ranges.
*
* @return \Illuminate\Http\JsonResponse
*/
public function rangesFiltered(): \Illuminate\Http\JsonResponse
{
$productModels = Range::query()
->where('published', true)
->orderBy('order', 'asc')
->get();
$productModels = CollectionHelper::paginateManually($productModels, 12, request()->page);
return response()->json($productModels);
}
}

View file

@ -110,10 +110,7 @@ class StaticPageController extends Controller
*/
public function contactForm(ContactRequest $request): \Illuminate\Http\RedirectResponse
{
$receivers = \config('mail.contactform.receiver');
foreach ($receivers as $email) {
Mail::to($email)->send(new SendContactMail((object)$request->validated()));
}
Mail::to(\config('mail.from.address'))->send(new SendContactMail((object)$request->validated()));
return redirect()->route('fo.contact.show')
->with(
@ -187,10 +184,7 @@ class StaticPageController extends Controller
*/
public function joinusForm(JoinusRequest $request): \Illuminate\Http\RedirectResponse
{
$receivers = \config('mail.contactform.receiver');
foreach ($receivers as $email) {
Mail::to($email)->send(new SendJoinusMail((object)$request->validated()));
}
Mail::to(\config('mail.from.address'))->send(new SendJoinusMail((object)$request->validated()));
return redirect()->route('fo.joinus.show')
->with(

View file

@ -65,6 +65,5 @@ class Kernel extends HttpKernel
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
'local-development' => \App\Http\Middleware\LocalDevelopment::class,
];
}

View file

@ -1,25 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class LocalDevelopment
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (app()->environment() != 'local') {
return abort(403, 'You are not authorized to access this');
}
return $next($request);
}
}

View file

@ -27,14 +27,14 @@ class UpdateConvictionpageRequest extends FormRequest
public function rules()
{
return [
'key_feed' => 'required|numeric|max:2147483647',
'key_earth_1' => 'required|numeric|max:2147483647',
'key_earth_2' => 'required|numeric|max:2147483647',
'key_together_1' => 'required|numeric|max:2147483647',
'key_together_2' => 'required|numeric|max:2147483647',
'key_together_3' => 'required|numeric|max:2147483647',
'key_together_4' => 'required|numeric|max:2147483647',
'key_territory' => 'required|numeric|max:2147483647',
'key_feed' => 'required|numeric',
'key_earth_1' => 'required|numeric',
'key_earth_2' => 'required|numeric',
'key_together_1' => 'required|numeric',
'key_together_2' => 'required|numeric',
'key_together_3' => 'required|numeric',
'key_together_4' => 'required|numeric',
'key_territory' => 'required|numeric',
];
}

View file

@ -54,7 +54,7 @@ class StoreNewsRequest extends FormRequest
'subtitle' => 'required|string|between:3,255',
'content' => 'required|string|min:15',
'published' => 'required|boolean',
'publish_at' => 'required|date',
'publish_at' => 'nullable|date',
'unpublish_at' => 'nullable|date|after:publish_at',
];

View file

@ -59,7 +59,7 @@ class StoreRangeRequest extends FormRequest
return \array_merge(
$rules,
$this->pictureRules('picture', 466, 440, 466, 440, false),
$this->pictureRules('picture_productsheet', 680, 300, 680, 300, false),
$this->pictureRules('picture_productsheet', 332, 442, 332, 442, false),
$this->pictureRules('picture_thumbnail', 246, 337, 246, 337, false),
);
}

View file

@ -31,11 +31,9 @@ class ContactRequest extends FormRequest
* Get the validation rules that apply to the request.
*
* @return array
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
public function rules()
{
// phpcs:enable
ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version'));
$rules = [
@ -45,96 +43,104 @@ class ContactRequest extends FormRequest
'society' => 'sometimes|nullable|string|between:3,255',
'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255',
'phone' => 'sometimes|nullable|numeric|min:0',
'address' => 'required|string|between:3,255',
'postal_code' => 'required|numeric|min:0',
'city' => 'required|string|between:3,255',
'address' => 'sometimes|nullable|string|between:3,255',
'postal_code' => 'sometimes|nullable|numeric|min:0',
'city' => 'sometimes|nullable|string|between:3,255',
'object' => ['required', new Enum(ObjectEnum::class)],
'message' => 'required|string|between:3,500',
'product_name' => [
'nullable', 'string', 'between:3,255',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_date_limit,product_barcode,product_lot,product_date_consumption,product_location',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_name'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_date_limit' => [
'sometimes', 'nullable', 'string', 'between:3,255',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_name,product_barcode,product_lot,product_date_consumption,product_location',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_date_limit'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_barcode' => [
'sometimes', 'nullable', 'numeric', 'min:0',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_name,product_date_limit,product_lot,product_date_consumption,product_location',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_barcode'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_lot' => [
'sometimes', 'nullable', 'numeric', 'min:0',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_name,product_date_limit,product_barcode,product_date_consumption,product_location',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_lot'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_date_consumption' => [
'sometimes', 'nullable', 'string', 'between:3,255',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_name,product_date_limit,product_barcode,product_lot,product_location',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_date_consumption'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_location' => [
'sometimes', 'nullable', 'string', 'between:3,255',
// @phpcs:ignore Generic.Files.LineLength.TooLong
'required_with:product_name,product_date_limit,product_barcode,product_lot,product_date_consumption',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_location'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'message' => 'required|string|between:3,255',
'accept_rules' => 'required|boolean',
'send_data' => 'required|boolean',
];
if ($this->object === strval(ObjectEnum::customerService->value())) {
$rules = \array_merge($rules, [
'product_name' => [
'string', 'between:3,255', 'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_name'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_date_limit' => [
'required', 'date',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_date_limit'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_barcode' => [
'numeric', 'min:0', 'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_barcode'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_lot' => [
'numeric', 'min:0', 'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_lot'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_date_consumption' => [
'required', 'date',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_date_consumption'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
'product_location' => [
'string', 'between:3,255', 'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
n\'est pas égale à :enumValue.', [
'field' => trans('validation.custom.product_location'),
'enumValue' => ObjectEnum::customerService->label(),
]));
}
}
],
]);
} //end if
if (
isset(request()->file) and
(request()->file->getClientMimeType() === "image/jpeg" ||
@ -155,20 +161,6 @@ class ContactRequest extends FormRequest
//phpcs:ignore Generic.Files.LineLength.TooLong
'file' => 'sometimes|nullable|mimes:pdf|required_with:product_name,product_date_limit,product_barcode,product_lot,product_date_consumption,product_location'
]);
} elseif (
isset(request()->file) and
(request()->file->getClientMimeType() !== "application/pdf") and
(request()->file->getClientMimeType() !== "image/jpeg") and
(request()->file->getClientMimeType() !== "image/png")
) {
$rules = \array_merge($rules, [
'file' => [
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
$fail(\trans('Le format du fichier doit être .jpg, .png ou .pdf'));
}
],
]);
} //end if
return $rules;
}

View file

@ -21,7 +21,7 @@ class JoinusRequest extends FormRequest
'first_name' => 'required|string|between:3,255',
'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255',
'phone' => 'required|numeric|min:0',
'message' => 'required|string|between:3,500',
'message' => 'required|string|between:3,255',
"file" => "sometimes|nullable|mimes:pdf|max:10000"
];
}

View file

@ -5,6 +5,7 @@ namespace App\Mail;
use App\Enums\Contact\ObjectEnum;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
@ -40,6 +41,13 @@ class SendContactMail extends Mailable
public function envelope(): \Illuminate\Mail\Mailables\Envelope
{
return new Envelope(
from: new Address(
$this->data->email,
($this->data->first_name !== null || $this->data->last_name !== null) ?
(($this->data->first_name ?? '') . " " . ($this->data->last_name ?? '')) :
null
),
to: [new Address(config('mail.from.address'), config('mail.from.name'))],
subject: sprintf('%s - %s', ObjectEnum::make($this->data->object)->label() ??
__('Nouveau message'), config('app.name')),
);

View file

@ -4,6 +4,7 @@ namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
@ -39,6 +40,13 @@ class SendJoinusMail extends Mailable
public function envelope(): \Illuminate\Mail\Mailables\Envelope
{
return new Envelope(
from: new Address(
$this->data->email,
($this->data->first_name !== null || $this->data->last_name !== null) ?
(($this->data->first_name ?? '') . " " . ($this->data->last_name ?? '')) :
null
),
to: [new Address(config('mail.from.address'), config('mail.from.name'))],
subject: sprintf('%s - %s', __('Candidature spontanée'), config('app.name')),
);
}

View file

@ -122,7 +122,7 @@ class ActivityLog extends Model
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
public function user()
{
return $this->belongsTo(User::class);
}

View file

@ -22,7 +22,7 @@ use Illuminate\Support\Str;
* @property string $picture Path of the picture (466px * 440px).
* @property string $picture_alt Picture alt attribute.
* @property string $picture_title Picture title attribute.
* @property string $picture_productsheet Path of the picture of the product sheet (680px * 300px).
* @property string $picture_productsheet Path of the picture of the product sheet (332px * 442px).
* @property string $picture_productsheet_alt Picture alt attribute of the product sheet.
* @property string $picture_productsheet_title Picture title attribute of the product sheet.
* @property string $picture_thumbnail Path of the thumbnail (246px * 337px).

View file

@ -5,7 +5,6 @@ namespace App\Models;
use App\Lib\Helpers\FileStorageHelper;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
/**
* @property string $picture Path of the picture (120px * 120px).
@ -55,14 +54,9 @@ class Stamp extends Model
});
static::updated(function (self $model) {
FileStorageHelper::removeOldFile($model, 'picture');
Cache::forget('randomStampsFooter');
});
static::deleted(function (self $model) {
FileStorageHelper::removeFile($model, 'picture');
Cache::forget('randomStampsFooter');
});
static::created(function () {
Cache::forget('randomStampsFooter');
});
}
}

View file

@ -4,7 +4,6 @@ namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
@ -21,7 +20,6 @@ class ViewServiceProvider extends ServiceProvider
$appInfos = Cache::remember('composer', 360, function () {
return json_decode(File::get(\app_path('../composer.json')));
});
// Share composer.json infos.
if (isset($appInfos->name) and isset($appInfos->version)) {
View::share('cpsr_name', $appInfos->name);
@ -36,24 +34,6 @@ class ViewServiceProvider extends ServiceProvider
} else {
Paginator::useBootstrapFive();
}
// Get all the stamps that are pubished.
$stamps = Cache::remember('randomStampsFooter', 360, function () {
return DB::table('stamps')
->select('picture', 'picture_alt', 'picture_title')
->where('published', true)
->get();
});
/**
* Share a collection of 1 or 2 random stamps for footer.
* First, check if $stamps is not empty, if not,
* we count if the number of stamp in $stamps is greater than 2.
* Then, pick 1 or 2 stamp(s) depending on the number of stamps.
*/
View::share(
'randomStampsFooter',
$stamps->isNotEmpty() ? $stamps->random($stamps->count() >= 2 ? 2 : 1) : []
);
}//end if
}
}
}

View file

@ -1,24 +1,22 @@
{
"name": "uwil/agis",
"version": "2.0.0",
"version": "1.0.0",
"type": "project",
"description": "Agis website.",
"require": {
"php": "^8.2",
"diglactic/laravel-breadcrumbs": "^8.0",
"doctrine/dbal": "^3.7",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"ldc/sitemap-generator": "^2.0",
"ldc/web-admin-secure-laravel": "^2.0",
"mews/purifier": "^3.4",
"sentry/sentry-laravel": "*",
"uwil/k8s-laravel": "^1.2"
"sentry/sentry-laravel": "*"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"kitloong/laravel-migrations-generator": "^6.8",
"krlove/eloquent-model-generator": "dev-l10-compatibility",
"laravel-lang/common": "^4.0",
"laravel/pint": "^1.0",
"laravel/sail": "^1.18",
@ -26,7 +24,8 @@
"nunomaduro/collision": "^7.0",
"phpunit/phpunit": "^10.0",
"slevomat/coding-standard": "^8.10",
"spatie/laravel-ignition": "^2.0"
"spatie/laravel-ignition": "^2.0",
"thedoctor0/laravel-factory-generator": "^1.2"
},
"autoload": {
"psr-4": {
@ -37,8 +36,8 @@
},
"repositories": [
{
"type": "composer",
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
"type": "vcs",
"url": "https://github.com/laravel-shift/eloquent-model-generator.git"
}
],
"autoload-dev": {

2306
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -96,10 +96,6 @@ return [
'name' => env('MAIL_FROM_NAME', 'Example'),
],
'contactform' => [
'receiver' => explode(',', env('MAIL_CONTACTFORM_RECEIVER', 'hello@example.com'))
],
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings

View file

@ -38,8 +38,4 @@ return [
'version' => env('GOOGLE_RECAPTCHA_VERSION', "3") === "3" ? true : false
]
],
'matomo' => [
'site_id' => env('MATOMO_SITE_ID')
]
];

View file

@ -1,101 +0,0 @@
<?php
use Spatie\Sitemap\Tags\Url;
return [
/**
* A list of url to ignore
* These are hard coded
* Each url does not have to be exhaustive
*
* For example, if you want to ignore all routes
* of the backoffice group
* just add 'bo' into this table
*
* * Note that this can take route names (both partially or full)
* * You can use a wild card just as for routeIs method
*/
'ignoreRoutes' => [
'back.*',
'bo.*',
'fo.verification.*',
'fo.password.*',
'front.frame',
'cspReportUri',
],
/**
* This should be filled using the command `php artisan sitemap:install-completer`
*
* 'completeWith' => [CLASS, 'METHOD'],
* eg : 'completeWith' => [CompleteSitemapWith::class, 'append'],
*
* This should point to a static method which will be called with the folowing parameter
* (LDC\SitemapGenerator\Lib\Sitemap $sitemap)
*
* You may now use $sitemap->addLinks('route.myRouteName', string[] $links)
*/
'completeWith' => null,
/**
* The default route frequency to use with sitemap generator
*/
'routeDefaultFrequency' => Url::CHANGE_FREQUENCY_DAILY,
/**
* The default route priority to use with sitemap generator
*
* priority should be a number between 0 and 1
* https://www.sitemaps.org/protocol.html
*/
'routeDefaultPriority' => 0.5,
/**
* Frequencies for routes
* use the full or partial route name as index
* and a frequency within \Spatie\Sitemap\Tags\Url constants
*
* eg: 'engagments.*' => \Spatie\Sitemap\Tags\Url::CHANGE_FREQUENCY_HOURLY
*/
'routeFrequencies' => [],
/**
* Priorities for routes
* use the full or partial route name as index
* and a priority in 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, and 0.0.
*
* 1.0 is the Highest
*
* eg: 'engagments.*' => 1.0
*/
'routePriorities' => [],
/**
* Enable or disable schedule for the job
* If set to true the sitemap generator will be run
* using the 'cron' instruction
*/
'schedule' => true,
/**
* If you want to set specific
* instruction for when to schedule job
* you can set this with a cron instruction
* You can generate one using https://crontab.guru/
*
* schedule must be set to true
*
* Default is every day at 15:45
*/
'cron' => '45 15 * * *',
/**
* The sitemap generator can execute JavaScript on each page so it will
* discover links that are generated by your JS scripts. This feature
* is powered by headless Chrome.
*
* ! This needs pupetter installed with npm : npm i puppeteer (not to put in dev dependencies)
*/
'executeJavascript' => true,
];

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -15,14 +15,14 @@ return new class extends Migration
{
Schema::create('convictionpages', function (Blueprint $table) {
$table->id();
$table->float('key_feed', 12)->comment('Chiffre clé \'bien nourrir\'');
$table->float('key_earth_1', 12)->comment('Chiffre clé \'respecter la terre\' 1');
$table->float('key_earth_2', 12)->comment('Chiffre clé \'respecter la terre\' 2');
$table->float('key_together_1', 12)->comment('Chiffre clé \'vivre ensemble\' 1');
$table->float('key_together_2', 12)->comment('Chiffre clé \'vivre ensemble\' 2');
$table->float('key_together_3', 12)->comment('Chiffre clé \'vivre ensemble\' 3');
$table->float('key_together_4', 12)->comment('Chiffre clé \'vivre ensemble\' 4');
$table->float('key_territory', 12)->comment('Chiffre clé \'intégrer son territoire\'');
$table->float('key_feed')->comment('Chiffre clé \'bien nourrir\'');
$table->float('key_earth_1')->comment('Chiffre clé \'respecter la terre\' 1');
$table->float('key_earth_2')->comment('Chiffre clé \'respecter la terre\' 2');
$table->float('key_together_1')->comment('Chiffre clé \'vivre ensemble\' 1');
$table->float('key_together_2')->comment('Chiffre clé \'vivre ensemble\' 2');
$table->float('key_together_3')->comment('Chiffre clé \'vivre ensemble\' 3');
$table->float('key_together_4')->comment('Chiffre clé \'vivre ensemble\' 4');
$table->float('key_territory')->comment('Chiffre clé \'intégrer son territoire\'');
$table->timestamps();
});
}

View file

@ -26,7 +26,7 @@ return new class extends Migration
$table->string('picture_alt')->comment('Attribut alt pour l\'image picture');
$table->string('picture_title')->comment('Attribut title pour l\'image picture');
$table->string('picture_productsheet')
->comment('Path de l\'image à afficher sur les fiches produits de cette gamme (680px * 300px)');
->comment('Path de l\'image à afficher sur les fiches produits de cette gamme (332px * 442px)');
$table->string('picture_productsheet_alt')
->comment('Attribut alt de l\'image à afficher sur les fiches produits');
$table->string('picture_productsheet_title')

View file

@ -21,7 +21,7 @@ class RangeSeeder extends Seeder
'../database/factories/assets/ranges/default-picture-466x440.png'
)));
$range->picture_productsheet = FileStorageHelper::storeFile($range, new \SplFileInfo(\resource_path(
'../database/factories/assets/ranges/default-picture-680x300.png'
'../database/factories/assets/ranges/default-picture-332x442.png'
)));
$range->picture_thumbnail = FileStorageHelper::storeFile($range, new \SplFileInfo(\resource_path(
'../database/factories/assets/ranges/default-picture-246x337.png'

View file

@ -1,177 +0,0 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ${CI_PROJECT_PATH_SLUG}-config-map
data:
APP_NAME: "${APP_APP_NAME}"
APP_ENV: "${APP_APP_ENV}"
APP_KEY: "${APP_APP_KEY}"
APP_DEBUG: "${APP_APP_DEBUG}"
APP_URL: "https://www.${APP_DOMAIN}"
LOG_CHANNEL: "k8s"
DB_HOST: "mariadb-service.common-services"
DB_DATABASE: "${APP_DB_DATABASE}"
DB_USERNAME: "${APP_DB_USERNAME}"
DB_PASSWORD: "${APP_DB_PASSWORD}"
MAIL_HOST: "${APP_MAIL_HOST}"
MAIL_PORT: "${APP_MAIL_PORT}"
MAIL_USERNAME: "${APP_MAIL_USERNAME}"
MAIL_PASSWORD: "${APP_MAIL_PASSWORD}"
MAIL_ENCRYPTION: "${APP_MAIL_ENCRYPTION}"
MAIL_FROM_ADDRESS: "${APP_MAIL_FROM_ADDRESS}"
MAIL_FROM_NAME: "${APP_APP_NAME}"
MAIL_CONTACTFORM_RECEIVER: "${APP_MAIL_CONTACTFORM_RECEIVER}"
LDC_WEB_API_KEY: "${APP_LDC_WEB_API_KEY}"
GOOGLE_RECAPTCHA_PRIVATE: "${APP_GOOGLE_RECAPTCHA_PRIVATE}"
GOOGLE_RECAPTCHA_PUBLIC: "${APP_GOOGLE_RECAPTCHA_PUBLIC}"
GOOGLE_RECAPTCHA_VERSION: "${APP_GOOGLE_RECAPTCHA_VERSION}"
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
MATOMO_SITE_ID: "${APP_MATOMO_SITE_ID}"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ${CI_PROJECT_PATH_SLUG}-pvc-storage
spec:
storageClassName: "csi-cinder-classic"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: $APP_PVC_SIZE
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${CI_PROJECT_PATH_SLUG}-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ${CI_PROJECT_PATH_SLUG}-app
template:
metadata:
labels:
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
imagePullSecrets:
- name: docker-registry-credentials
securityContext:
runAsUser: 33
runAsGroup: 33
fsGroup: 33
fsGroupChangePolicy: "OnRootMismatch"
volumes:
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
---
apiVersion: v1
kind: Service
metadata:
name: ${CI_PROJECT_PATH_SLUG}-service
spec:
selector:
app: ${CI_PROJECT_PATH_SLUG}-app
ports:
- port: 80
targetPort: 443
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`${APP_DOMAIN}`, `www.${APP_DOMAIN}`)
kind: Rule
services:
- name: ${CI_PROJECT_PATH_SLUG}-service
port: 80
middlewares:
- name: redirect-no-www-to-www
namespace: common-services
tls:
secretName: $APP_DOMAIN
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: $APP_DOMAIN
spec:
dnsNames:
- $APP_DOMAIN
- www.${APP_DOMAIN}
secretName: $APP_DOMAIN
issuerRef:
name: $APP_CERT_ISSUER
kind: ClusterIssuer
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: ${CI_PROJECT_PATH_SLUG}-cronjob
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- 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: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
securityContext:
runAsUser: 33
runAsGroup: 33
fsGroup: 33
fsGroupChangePolicy: "OnRootMismatch"
restartPolicy: OnFailure

8
package-lock.json generated
View file

@ -12,7 +12,7 @@
"@fortawesome/free-regular-svg-icons": "latest",
"@fortawesome/free-solid-svg-icons": "latest",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@ldc-web/cookie-notice": "^3.1.2",
"@ldc-web/cookie-notice": "^3.0.9",
"@sipec/vue3-tags-input": "^3.0.4",
"@types/bootstrap": "^5.2.7",
"@types/node": "^20.8.2",
@ -2419,9 +2419,9 @@
"dev": true
},
"node_modules/@ldc-web/cookie-notice": {
"version": "3.1.2",
"resolved": "https://lab.s-web.fr/api/v4/projects/50/packages/npm/@ldc-web/cookie-notice/-/@ldc-web/cookie-notice-3.1.2.tgz",
"integrity": "sha1-UNRi9oPfcnrw4lfGSh4wDUqqcIU=",
"version": "3.0.9",
"resolved": "https://lab.s-web.fr/api/v4/projects/50/packages/npm/@ldc-web/cookie-notice/-/@ldc-web/cookie-notice-3.0.9.tgz",
"integrity": "sha1-zU6WMyLg3pHdeT0K9i25HeQ8+Ik=",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {

View file

@ -20,7 +20,7 @@
"@fortawesome/free-regular-svg-icons": "latest",
"@fortawesome/free-solid-svg-icons": "latest",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@ldc-web/cookie-notice": "^3.1.2",
"@ldc-web/cookie-notice": "^3.0.9",
"@sipec/vue3-tags-input": "^3.0.4",
"@types/bootstrap": "^5.2.7",
"@types/node": "^20.8.2",
@ -57,16 +57,16 @@
"terser": "latest",
"toastify-js": "^1.12.0",
"ts-loader": "^9.3.1",
"typescript": "latest",
"typescript-eslint": "latest",
"vite": "^4.0.0",
"typescript": "latest",
"vite-plugin-babel": "latest",
"vite-plugin-checker": "latest",
"vite-plugin-eslint": "latest",
"vite-plugin-stylelint": "latest",
"vue": "latest",
"vite": "^4.0.0",
"vue-eslint-parser": "^9.1.0",
"vue-loader": "^16.8.3",
"vue": "latest",
"vue-tsc": "1.6.0"
}
}

View file

@ -221,70 +221,69 @@ return [
'female' => 'of the ',
'vowel' => 'of the '
],
'accept_rules' => 'acceptation of rules',
'activated' => 'activated',
'attribute_alt' => 'alt attribute',
'attribute_title' => 'title attribute',
'background' => 'background',
'category' => 'category',
'category' => 'category',
'civility' => 'civility',
'cooking_advice' => 'cooking advice',
'description' => 'description',
'direction' => 'direction',
'event' => 'event',
'file' => 'file',
'ingredients' => 'ingredients',
'job' => 'job',
'key_earth_1' => 'key number for "respect the earth" 1',
'key_earth_2' => 'key number for "respect the earth" 2',
'key_feed' => 'key number for "feed well"',
'key_territory' => 'key number for "integrate its territory"',
'key_together_1' => 'key number for "live together" 1',
'key_together_2' => 'key number for "live together" 2',
'key_together_3' => 'key number for "live together" 3',
'key_together_4' => 'key number for "live together" 4',
'model' => 'target element',
'nutritionnal_values' => 'nutritionnal values',
'object' => 'object',
'order' => 'order',
'picture_1' => 'picture one',
'picture_2' => 'picture two',
'picture_3' => 'picture three',
'picture_alt' => 'attribut alt of the :field',
'picture_ambiance' => 'ambiance picture',
'picture_packshot' => 'packshot picture',
'picture_productsheet' => 'productsheet picture',
'picture_thumbnail' => 'thumbnail',
'picture_title' => 'attribut title of the :field',
'picture' => 'picture',
'presentation_content' => 'presentation content',
'presentation_title' => 'presentation title',
'product_barcode' => 'product barcode',
'product_barcode_detail' => '(13 digits)',
'product_date_consumption' => 'product date consumption',
'product_date_limit' => 'product date limit',
'product_location' => 'product location',
'product_lot' => 'product lot',
'product_name' => 'product name',
'publication' => 'publication',
'publish_at' => 'publication date',
'publish_at' => 'publication date',
'send_data' => 'autorization to send data',
'seo_description' => 'SEO description',
'seo_title' => 'SEO title',
'seo' => 'SEO',
'society' => 'society',
'static_page_type' => 'static page type',
'statut' => 'statut',
'subtitle' => 'subtitle',
'tagline' => 'tagline',
'target' => 'target',
'title_part1' => 'title part one',
'title_part2' => 'title part two',
'title_part3' => 'title part three',
'unpublish_at' => 'end of publication date',
'unpublish_at' => 'end of publication date',
'video_id' => 'ID of the video',
'accept_rules' => 'acceptation of rules',
'activated' => 'activated',
'attribute_alt' => 'alt attribute',
'attribute_title' => 'title attribute',
'background' => 'background',
'category' => 'category',
'category' => 'category',
'civility' => 'civility',
'cooking_advice' => 'cooking advice',
'description' => 'description',
'direction' => 'direction',
'event' => 'event',
'file' => 'file',
'ingredients' => 'ingredients',
'job' => 'job',
'key_earth_1' => 'key number for "respect the earth" 1',
'key_earth_2' => 'key number for "respect the earth" 2',
'key_feed' => 'key number for "feed well"',
'key_territory' => 'key number for "integrate its territory"',
'key_together_1' => 'key number for "live together" 1',
'key_together_2' => 'key number for "live together" 2',
'key_together_3' => 'key number for "live together" 3',
'key_together_4' => 'key number for "live together" 4',
'model' => 'target element',
'nutritionnal_values' => 'nutritionnal values',
'object' => 'object',
'order' => 'order',
'picture_1' => 'picture one',
'picture_2' => 'picture two',
'picture_3' => 'picture three',
'picture_alt' => 'attribut alt of the :field',
'picture_ambiance' => 'ambiance picture',
'picture_packshot' => 'packshot picture',
'picture_productsheet' => 'productsheet picture',
'picture_thumbnail' => 'thumbnail',
'picture_title' => 'attribut title of the :field',
'picture' => 'picture',
'presentation_content' => 'presentation content',
'presentation_title' => 'presentation title',
'product_barcode' => 'product barcode',
'product_date_consumption' => 'product date consumption',
'product_date_limit' => 'product date limit',
'product_location' => 'product location',
'product_lot' => 'product lot',
'product_name' => 'product name',
'publication' => 'publication',
'publish_at' => 'publication date',
'publish_at' => 'publication date',
'send_data' => 'autorization to send data',
'seo_description' => 'SEO description',
'seo_title' => 'SEO title',
'seo' => 'SEO',
'society' => 'society',
'static_page_type' => 'static page type',
'statut' => 'statut',
'subtitle' => 'subtitle',
'tagline' => 'tagline',
'target' => 'target',
'title_part1' => 'title part one',
'title_part2' => 'title part two',
'title_part3' => 'title part three',
'unpublish_at' => 'end of publication date',
'unpublish_at' => 'end of publication date',
'video_id' => 'ID of the video',
],
];

View file

@ -223,70 +223,69 @@ return [
'female' => 'de la ',
'vowel' => 'de l\''
],
'accept_rules' => 'acceptation des règles',
'activated' => 'activé',
'attribute_alt' => 'attribut alt',
'attribute_title' => 'attribut title',
'background' => 'fond',
'category' => 'catégorie',
'category' => 'catégorie',
'civility' => 'civilité',
'cooking_advice' => 'conseil de réchauffage',
'description' => 'description',
'direction' => 'direction',
'event' => 'évènement',
'file' => 'fichier',
'ingredients' => 'ingrédients',
'job' => 'métier',
'key_earth_1' => 'Chiffre clé "respecter la terre" 1',
'key_earth_2' => 'Chiffre clé "respecter la terre" 2',
'key_feed' => 'chiffre clé "bien nourrir"',
'key_territory' => 'Chiffre clé "intégrer son territoire"',
'key_together_1' => 'Chiffre clé "vivre ensemble" 1',
'key_together_2' => 'Chiffre clé "vivre ensemble" 2',
'key_together_3' => 'Chiffre clé "vivre ensemble" 3',
'key_together_4' => 'Chiffre clé "vivre ensemble" 4',
'model' => 'élément ciblé',
'nutritionnal_values' => 'valeurs nutritionnelles',
'object' => 'objet',
'order' => 'ordre',
'picture_1' => 'image une',
'picture_2' => 'image deux',
'picture_3' => 'image trois',
'picture_alt' => 'attribut alt de l\':field',
'picture_ambiance' => 'image d\'ambiance',
'picture_packshot' => 'image du packshot',
'picture_productsheet' => 'image de la fiche produit',
'picture_thumbnail' => 'vignette',
'picture_title' => 'attribut title de l\':field',
'picture' => 'image',
'presentation_content' => 'contenu de présentation',
'presentation_title' => 'titre de présentation',
'product_barcode' => 'code barre du produit',
'product_barcode_detail' => '(13 chiffres)',
'product_date_consumption' => 'date de consommation',
'product_date_limit' => 'date de limite de consommation',
'product_location' => 'le lieu de l\'achat',
'product_lot' => 'numéro du lot figurant à côté de la date',
'product_name' => 'nom du produit',
'publication' => 'publication',
'publish_at' => 'date de publication',
'publish_at' => 'date de publication',
'send_data' => 'autorisation d\'enregistrer des données',
'seo_description' => 'description SEO',
'seo_title' => 'titre SEO',
'seo' => 'référencement SEO',
'society' => 'société',
'static_page_type' => 'type de page',
'statut' => 'statut',
'subtitle' => 'sous-titre',
'tagline' => 'phrase d\'accroche',
'target' => 'cible',
'title_part1' => 'première partie du titre',
'title_part2' => 'seconde partie du titre',
'title_part3' => 'dernière partie du titre',
'unpublish_at' => 'date de fin de publication',
'unpublish_at' => 'date de fin de publication',
'video_id' => 'ID de la vidéo',
'accept_rules' => 'acceptation des règles',
'activated' => 'activé',
'attribute_alt' => 'attribut alt',
'attribute_title' => 'attribut title',
'background' => 'fond',
'category' => 'catégorie',
'category' => 'catégorie',
'civility' => 'civilité',
'cooking_advice' => 'conseil de réchauffage',
'description' => 'description',
'direction' => 'direction',
'event' => 'évènement',
'file' => 'fichier',
'ingredients' => 'ingrédients',
'job' => 'métier',
'key_earth_1' => 'Chiffre clé "respecter la terre" 1',
'key_earth_2' => 'Chiffre clé "respecter la terre" 2',
'key_feed' => 'chiffre clé "bien nourrir"',
'key_territory' => 'Chiffre clé "intégrer son territoire"',
'key_together_1' => 'Chiffre clé "vivre ensemble" 1',
'key_together_2' => 'Chiffre clé "vivre ensemble" 2',
'key_together_3' => 'Chiffre clé "vivre ensemble" 3',
'key_together_4' => 'Chiffre clé "vivre ensemble" 4',
'model' => 'élément ciblé',
'nutritionnal_values' => 'valeurs nutritionnelles',
'object' => 'objet',
'order' => 'ordre',
'picture_1' => 'image une',
'picture_2' => 'image deux',
'picture_3' => 'image trois',
'picture_alt' => 'attribut alt de l\':field',
'picture_ambiance' => 'image d\'ambiance',
'picture_packshot' => 'image du packshot',
'picture_productsheet' => 'image de la fiche produit',
'picture_thumbnail' => 'vignette',
'picture_title' => 'attribut title de l\':field',
'picture' => 'image',
'presentation_content' => 'contenu de présentation',
'presentation_title' => 'titre de présentation',
'product_barcode' => 'le code barre du produit',
'product_date_consumption' => 'date de consommation',
'product_date_limit' => 'date de limite de consommation',
'product_location' => 'le lieu de l\'achat',
'product_lot' => 'numéro du lot figurant à côté de la date',
'product_name' => 'nom du produit',
'publication' => 'publication',
'publish_at' => 'date de publication',
'publish_at' => 'date de publication',
'send_data' => 'autorisation d\'enregistrer des données',
'seo_description' => 'description SEO',
'seo_title' => 'titre SEO',
'seo' => 'référencement SEO',
'society' => 'société',
'static_page_type' => 'type de page',
'statut' => 'statut',
'subtitle' => 'sous-titre',
'tagline' => 'phrase d\'accroche',
'target' => 'cible',
'title_part1' => 'première partie du titre',
'title_part2' => 'seconde partie du titre',
'title_part3' => 'dernière partie du titre',
'unpublish_at' => 'date de fin de publication',
'unpublish_at' => 'date de fin de publication',
'video_id' => 'ID de la vidéo',
],
];

View file

@ -1,9 +1,5 @@
img { max-width: 100%; }
a {
color: $color-dark;
}
.form-check-input[type="checkbox"]:checked {
#{--bs-form-check-bg-image}: url("@/images/global/checkbox-cross.svg");
border-color: var(--bs-form-check-bg);

View file

@ -55,11 +55,6 @@
background-repeat: no-repeat;
background-size: 100% 100%;
}
&-img-container {
width: 134px;
height: 148px !important;
}
}
}

View file

@ -19,7 +19,6 @@
.seasonal-sections {
.seasonal-sections-image {
width: max-content;
height: min-content;
&.bg-agis-white {
@ -97,7 +96,7 @@
&::before {
position: absolute;
top: 0;
left: -19rem;
left: -20rem;
display: none;
width: 500px;
height: 500px;

View file

@ -1,30 +1,40 @@
.news {
.fs-news {
font-size: calc(1.375rem + 3.2vw)
}
.swiper-button {
&-prev,
&-next { width: 3rem; }
&-next { rotate: 180deg; }
&-disabled { opacity: .5; }
}
.swiper-slide {
&-content {
width: auto;
}
}
&-category-arrow{
width: 2rem;
height: 2rem;
rotate: 180deg;
}
&-show-w-85{
width: 85%;
}
}
.news-single {
&-img.bg-agis-white {
background-position: bottom;
background-size: 100% 85%;
}
&-content{
h3 {
width: fit-content;
padding-right: 1rem;
padding-left: 1rem;
background: url("@/images/global/bg-title.svg");
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
color: #fff;
font-family: 'Readex Pro', sans-serif !important;
font-size: x-large;
}
h2 {
font-family: $font-family-base;
font-size: xx-large;
font-weight: 600;
}
}
&-title {
width: 100%;
}

View file

@ -52,12 +52,6 @@
.picto-img {
width: 35%;
}
.cooking-advice {
ul {
list-style-position: inside;
}
}
}
.swiper-product-pictures,

View file

@ -6,6 +6,61 @@
&-img {
max-width: 15rem;
}
&-swiper {
.swiper-ranges {
position: relative;
.swiper-slide {
&-content {
width: 246px;
p {
hyphens: auto;
line-height: 1.2em;
word-break: break-word;
}
}
&-range {
max-width: 332px;
}
}
.swiper-button {
&-prev,
&-next { width: 3rem; }
&-next { rotate: 180deg; }
&-disabled { opacity: .5; }
}
}
}
&-flexwrap {
.col-4:nth-child(1),
.col-4:nth-child(3) {
transform: translateY(-3rem);
}
.card {
width: calc(246px + 3rem);
&-header {
height: 4em;
}
.card-body div {
transition: .3s ease-in-out;
}
&:hover .card-body div {
opacity: 1 !important;
visibility: visible !important;
}
}
}
}
.range {

View file

@ -1,10 +1,7 @@
<template>
<div class="items-list container">
<div class="news-list container">
<!-- TITLE & SELECT -->
<div
v-if="showSelect"
class="row pt-5"
>
<div class="row pt-5">
<div class="col-12 col-lg-6">
<div class="ranges-title w-100 w-lg-fit">
<span class="divide d-block w-100 mt-xl-3 my-2" />
@ -20,7 +17,7 @@
<select
class="form-control highlight yellow"
role="button"
@change="updateItems(1)"
@change="updateNews(1)"
:disabled="intLoading"
>
<option
@ -43,73 +40,40 @@
</div>
<!-- MOBILE: SLIDER -->
<div
class="items-slider d-block d-lg-none bg-agis-white pb-5"
:class="(itemModels.length) ? '' : 'd-none'"
class="news-slider d-block d-lg-none bg-agis-white pb-5"
:class="(newsModels.length) ? '' : 'd-none'"
>
<div class="swiper swiper-items overflow-hidden">
<div class="swiper swiper-news overflow-hidden">
<div
class="swiper-wrapper"
@touchend="checkActiveSlide()"
>
<div
class="swiper-slide swiper-slide-content"
v-for="(item, id) in itemModels"
v-for="(news, id) in newsModels"
:key="id"
>
<div class="swiper-slide-items-container">
<div class="swiper-slide-news-container">
<div class="mx-auto p-4">
<p
v-if="rangeId === null && !showSelect"
class="text-primary text-center f-readex-pro p-0"
>
{{ item.title }}
</p>
<img
class="card-img-top"
:src="urlPathBase + (item.picture_thumbnail as string)"
:alt="(item.picture_thumbnail_alt as string)"
:title="(item.picture_thumbnail_title as string)"
:src="(news.picture_thumbnail as string)"
:alt="(news.picture_thumbnail_alt as string)"
:title="(news.picture_thumbnail_title as string)"
>
<div class="card-body">
<template v-if="rangeId === null && !showSelect">
<p class="card-text m-0">
{{ item.tagline }}
</p>
<a
class="card-text m-0"
:href="getShowItemRoute(item.slug as string)"
>
{{ __('> En savoir +') }}
</a>
</template>
<template v-if="showSelect">
<p class="card-text m-0">
{{ new Date(item.publish_at as string).toLocaleDateString() }}
</p>
<p class="card-text m-0">
{{ item.title }}
</p>
<a
class="card-text m-0"
:href="getShowItemRoute(item.slug as string)"
>
{{ __('> Lire la suite') }}
</a>
</template>
<template v-if="rangeId !== null">
<p class="card-text fw-bold m-0">
{{ item.title }}
</p>
<p class="card-text m-0">
{{ item.subtitle }}
</p>
<a
class="card-text m-0"
:href="getShowItemRoute(item.slug as string)"
>
{{ __('> En savoir +') }}
</a>
</template>
<p class="card-text m-0">
{{ new Date(news.publish_at as string).toLocaleDateString() }}
</p>
<p class="card-text m-0">
{{ news.title }}
</p>
<a
class="card-text m-0"
:href="getShowNewsRoute(news.slug as string)"
>
{{ __('> Lire la suite') }}
</a>
</div>
</div>
</div>
@ -128,8 +92,7 @@
<button
v-if="intLoadingMore"
class="btn btn-primary"
:title="__('Cliquer pour charger la suite')"
@click="updateItems(page + 1, true)"
@click="updateNews(page + 1, true)"
>
{{ __('> Charger plus') }}
</button>
@ -149,10 +112,7 @@
</div>
</div>
<!-- DESKTOP: FLEX WRAP -->
<div
class="position-relative d-none d-lg-flex row my-4"
:class="(rangeId === null && !showSelect) ? 'ranges-flexwrap' : ((showSelect) ? 'news-flexwrap' : 'range-flexwrap')"
>
<div class="position-relative d-none d-lg-flex row my-4">
<template v-if="intLoading">
<div class="position-absolute top-0 left-0 bg-secondary w-100 h-100 d-flex justify-content-center align-items-center bg-opacity-25 z-1">
<div
@ -168,7 +128,7 @@
class="cards-container col-4"
>
<div
class="card bg-transparent border-0 bg-agis-white d-flex flex-column p-4 my-2"
class="bg-agis-white d-flex flex-column p-4 my-2"
:class="((index % 3 === 0) ? 'ms-auto' : (((index % 3 === 1)) ? 'me-auto' : 'mx-auto'))"
>
<div class="placeholder-glow">
@ -183,80 +143,45 @@
</template>
<div
v-else
v-for="(item, id) in itemModels"
v-for="(news, id) in newsModels"
:key="id"
class="cards-container col-4"
>
<div
class="card border-0 bg-transparent bg-agis-white d-flex flex-column p-4 my-2"
:class="((id % 3 === 0) ? 'ms-0 me-auto' : (((id % 3 === 1)) ? 'mx-auto' : 'ms-auto me-0'))"
class="bg-agis-white d-flex flex-column p-4 my-2"
:class="((id % 3 === 0) ? 'me-auto' : (((id % 3 === 1)) ? 'mx-auto' : 'ms-auto'))"
>
<div class="text-center">
<template v-if="rangeId === null && !showSelect">
<p class="text-dark f-readex-pro p-0">
{{ item.title }}
</p>
<a
:href="getShowItemRoute(item.slug as string)"
class="stretched-link"
/>
</template>
<div class="w-fit position-relative">
<div class="card-range-hover position-absolute top-0 start-0 w-100 h-100 bg-opacity-50 bg-light p-2">
<p class="text-dark f-readex-pro p-0">
{{ String(item.subtitle).substring(0,100) + (String(item.subtitle).length > 100 ? '...' : '') }}
</p>
</div>
<img
class="img-fluid w-auto"
:src="urlPathBase + (item.picture_thumbnail as string)"
:alt="(item.picture_thumbnail_alt as string)"
:title="(item.picture_thumbnail_title as string)"
>
</div>
<img
class="img-fluid w-auto"
:src="(news.picture_thumbnail as string)"
:alt="(news.picture_thumbnail_alt as string)"
:title="(news.picture_thumbnail_title as string)"
>
</div>
<div class="card-body py-2 px-0">
<template v-if="showSelect">
<div class="card-body">
<p class="card-text m-0">
{{ new Date(news.publish_at as string).toLocaleDateString() }}
</p>
<p class="card-text m-0">
{{ news.title }}
</p>
<a
class="card-text m-0"
:href="getShowNewsRoute(news.slug as string)"
>
{{ __('> Lire la suite') }}
</a>
<template
v-for="(categoryEnum, categoryEnumIndex) in categoryEnums"
:key="categoryEnumIndex"
>
<p
v-if="showSelect"
class="card-text m-0"
v-if="news.category === categoryEnum.value"
>
{{ new Date(item.publish_at as string).toLocaleDateString() }}
{{ categoryEnum.label }}
</p>
<p class="card-text m-0">
{{ item.title }}
</p>
<a
class="card-text m-0"
:href="getShowItemRoute(item.slug as string)"
>
{{ __('> Lire la suite') }}
</a>
<template
v-for="(categoryEnum, categoryEnumIndex) in categoryEnums"
:key="categoryEnumIndex"
>
<p
class="card-text m-0"
v-if="item.category === categoryEnum.value"
>
{{ categoryEnum.label }}
</p>
</template>
</template>
<template v-if="rangeId !== null">
<p class="card-text fw-bold mb-1">
{{ item.title }}
</p>
<p class="card-text m-0">
{{ item.subtitle }}
</p>
<a
class="card-text stretched-link m-0"
:href="getShowItemRoute(item.slug as string)"
>
{{ __('> En savoir +') }}
</a>
</template>
</div>
</div>
@ -293,12 +218,12 @@
</ul>
</nav>
</div>
<!-- NO ITEMS -->
<!-- NO NEWS -->
<p
v-if="!intLoading"
:class="(itemModels.length <= 0) ? '' : 'd-none'"
:class="(newsModels.length <= 0) ? '' : 'd-none'"
>
{{ __('Aucune :name n\'est disponible', {'name': modelName}) }}
{{ __('Aucune actualité n\'est disponible') }}
</p>
</div>
</template>
@ -312,11 +237,11 @@ import route from "./../../modules/route";
import trans from "./../../modules/trans";
export default defineComponent({
name: "ItemsListComponent",
name: "NewsListComponent",
mixins: [trans, route, parseLaravelErrorMessages],
data(): {
itemModels: LaravelModelList;
itemsFilteredRoute: string;
newsModels: LaravelModelList;
newsFilteredRoute: string;
categoryEnums: {
label: string,
name: string,
@ -326,25 +251,19 @@ export default defineComponent({
swiper: Swiper|null,
intLoading: boolean,
intLoadingMore: boolean,
concatItemsFiltered: boolean,
concatNewsFiltered: boolean,
page: number;
paginator: LaravelPaginator;
routeFiltered: string;
routeShow: string;
showSelect: boolean;
modelName: string;
rangeId: number;
urlPathBase: string;
} {
return {
itemModels: [],
itemsFilteredRoute: "",
newsModels: [],
newsFilteredRoute: "",
categoryEnums: [],
selectedValue: 0,
swiper: null,
intLoading: false,
intLoadingMore: false,
concatItemsFiltered: false,
concatNewsFiltered: false,
page: 1,
paginator: {
current_page: 1,
@ -360,51 +279,36 @@ export default defineComponent({
to: 1,
total: 1,
},
routeFiltered: "",
routeShow: "",
showSelect: false,
modelName: "",
rangeId: 0,
urlPathBase: "",
};
},
computed: {},
mounted() {
const json = String(this.$attrs.json ?? "{}"),
data = JSON.parse(json);
this.modelName = data.modelName;
this.itemModels = data.itemModels.data;
this.paginator = data.itemModels;
this.categoryEnums = data.categoryEnums ?? null;
this.routeFiltered = data.routeFiltered;
this.routeShow = data.routeShow;
this.showSelect = data.showSelect;
this.rangeId = data.range_id ?? null;
this.urlPathBase = window.location.origin + "/";
if (this.showSelect) {
this.$nextTick(() => {
this.initSelect();
});
}
this.newsModels = data.newsModels.data;
this.paginator = data.newsModels;
this.categoryEnums = data.categoryEnums;
this.initSelect();
this.initSwiper();
},
methods: {
/** Init select ::after animation */
initSelect(): void {
const contactFormSelectList = document.querySelectorAll(".items-list .select-form select") as NodeListOf<HTMLSelectElement>;
const contactFormSelectList = document.querySelectorAll(".news-list .select-form select") as NodeListOf<HTMLSelectElement>;
document.body.addEventListener("click", function (e: MouseEvent) {
const target = e.target as HTMLElement | null;
contactFormSelectList.forEach(select => {
if (select.contains(target)) {
select.parentElement?.classList.toggle("active");
select.parentElement!.classList.toggle("active");
} else {
select.parentElement?.classList.remove("active");
select.parentElement!.classList.remove("active");
}
});
});
},
/** Init items slider */
/** Init news slider */
initSwiper(): void {
this.swiper = new Swiper(".swiper-items", {
this.swiper = new Swiper(".swiper-news", {
modules: [Navigation],
grabCursor: true,
slidesPerView: 1,
@ -414,45 +318,39 @@ export default defineComponent({
prevEl: ".swiper-button-prev",
},
});
this.checkActiveSlide();
this.swiper.on("slideChange", () => {
setTimeout(this.checkActiveSlide, 300);
});
},
/** Get selected value */
getSelectedValue(): number {
let target = document.querySelector(".items-list .select-form select") as HTMLSelectElement | null;
let target = document.querySelector(".news-list .select-form select") as HTMLSelectElement | null;
return Number(target?.value);
},
/** Get filtered items route */
getFilteredItemsRoute(): string {
const route = this.route(this.routeFiltered);
/** Get filtered news route */
getFilteredNewsRoute(): string {
const route = this.route("fo.news.filtered");
if (!route) {
throw new Error("Undefined route " + this.routeFiltered);
throw new Error("Undefined route fo.news.filtered");
}
return route + "?page=" + this.page +
((this.showSelect != null) ? "&category=" + this.selectedValue : "") +
((this.rangeId != null) ? "&range_id=" + this.rangeId : "");
return route + "?page=" + this.page + "&category=" + this.selectedValue;
},
/** Get show item route */
getShowItemRoute(slug: string): string {
const route = this.route(this.routeShow, {
/** Get show news route */
getShowNewsRoute(slug: string): string {
const route = this.route("fo.news.show", {
SLUG: slug,
});
if (!route) {
throw new Error("Undefined route " + this.routeShow);
throw new Error("Undefined route fo.news.show");
}
return route;
},
/** Get filtered items */
getFilteredItems(): void {
/** Get filtered news */
getFilteredNews(): void {
window.axios
.get(this.itemsFilteredRoute)
.get(this.newsFilteredRoute)
.then((response) => {
if (this.intLoadingMore && this.concatItemsFiltered) {
this.itemModels = this.itemModels.concat(Object.values(response.data.data));
if (this.intLoadingMore && this.concatNewsFiltered) {
this.newsModels = this.newsModels.concat(Object.values(response.data.data));
} else {
this.itemModels = Object.values(response.data.data);
this.newsModels = Object.values(response.data.data);
}
this.paginator = response.data;
this.intLoading = false;
@ -490,16 +388,14 @@ export default defineComponent({
}
console.log(message);
},
/** Update items with filtered items */
updateItems(page: number, concat = false as boolean): void {
this.concatItemsFiltered = concat;
/** Update news with filtered news */
updateNews(page: number, concat = false as boolean): void {
this.concatNewsFiltered = concat;
this.page = page;
this.intLoading = true;
if (this.showSelect) {
this.selectedValue = this.getSelectedValue();
}
this.itemsFilteredRoute = this.getFilteredItemsRoute();
this.getFilteredItems();
this.selectedValue = this.getSelectedValue();
this.newsFilteredRoute = this.getFilteredNewsRoute();
this.getFilteredNews();
},
/** Get all links from the paginator */
navigateOnPage(pageUrl: string): void {
@ -507,7 +403,7 @@ export default defineComponent({
this.page = Number.parseInt(
String(new URL(pageUrl).searchParams.get("page") ?? 1)
);
this.updateItems(this.page);
this.updateNews(this.page);
},
/** Check if it's the last slide is activated */
checkActiveSlide(): void {
@ -527,42 +423,7 @@ export default defineComponent({
@import "./../../../../node_modules/bootstrap/scss/functions";
@import "./../../../../node_modules/bootstrap/scss/variables";
@import "./../../../../node_modules/bootstrap/scss/mixins";
.items-list {
.swiper .swiper-button {
&-prev,
&-next { width: 3rem; }
&-next { rotate: 180deg; }
&-disabled { opacity: .5; }
}
.card-range-hover {
opacity: 0;
visibility: hidden;
transition: .3s;
}
.news-flexwrap .card {
max-width: calc(265px + 3rem);
}
.ranges-flexwrap {
.col-4:nth-child(1),
.col-4:nth-child(3) {
transform: translateY(-3rem);
}
.card {
max-width: calc(246px + 3rem);
&:hover .card-range-hover {
opacity: 1;
visibility: visible;
}
}
}
.range-flexwrap .card {
max-width: calc(332px + 3rem);
}
.cards-container .bg-agis-white .placeholder-image {
max-width: 265px;
width: 100%;
height: 354px;
}
.news-list {
.select-form {
width: 100%;
@include media-breakpoint-up(lg) {
@ -593,5 +454,13 @@ export default defineComponent({
transform: rotate(270deg);
}
}
.cards-container .bg-agis-white {
max-width: 314px;
.placeholder-image {
max-width: 265px;
width: 100%;
height: 354px;
}
}
}
</style>

View file

@ -353,7 +353,6 @@
'id' => 'newsPublishedAt',
'name' => 'publish_at',
'model' => $newsModel ?? null,
'required' => true,
'helper' => __('crud.helpers.publish_at', [
'model' => __('models.classes.news'),
]),

View file

@ -340,12 +340,12 @@
@include('bo.partials.inputs.varchar-picture', [
'id' => 'rangePictureProductsheet',
'name' => 'picture_productsheet',
'width' => 680,
'height' => 300,
'width' => 332,
'height' => 442,
'model' => $rangeModel ?? null,
'helper' => __('crud.minicrud.dimensions_must_be', [
'widthpx' => '680px',
'heightpx' => '300px',
'widthpx' => '332px',
'heightpx' => '442px',
]),
'required' => true,
'preview' => true,

View file

@ -18,23 +18,24 @@
- **{{ __('validation.attributes.message') }}:** {{ $data->message }}
@endcomponent
@if (
!empty($data->product_name) ||
!empty($data->product_date_limit) ||
!empty($data->product_barcode) ||
!empty($data->product_lot) ||
!empty($data->product_date_consumption) ||
!empty($data->product_location))
@if(
$data->product_name !== null ||
$data->product_date_limit !== null ||
$data->product_barcode !== null ||
$data->product_lot !== null ||
$data->product_date_consumption !== null ||
$data->product_location !== null
)
### Information sur le produit:
@component('mail::panel')
- **{{ __('validation.custom.product_name') }}:** {{ $data->product_name ?? '' }}
- **{{ __('validation.custom.product_date_limit') }}:** {{ \Carbon\Carbon::make($data->product_date_limit)->format('d/m/Y') ?? '' }}
- **{{ __('validation.custom.product_date_limit') }}:** {{ $data->product_date_limit ?? '' }}
- **{{ __('validation.custom.product_barcode') }}:** {{ $data->product_barcode ?? '' }}
- **{{ __('validation.custom.product_lot') }}:** {{ $data->product_lot ?? '' }}
- **{{ __('validation.custom.product_date_consumption') }}:** {{ \Carbon\Carbon::make($data->product_date_consumption)->format('d/m/Y') ?? '' }}
- **{{ __('validation.custom.product_date_consumption') }}:** {{ $data->product_date_consumption ?? '' }}
- **{{ __('validation.custom.product_location') }}:** {{ $data->product_location ?? '' }}
@endcomponent
@endif
L'équipe {{ config('app.name') }}.
L'équipe {{ config('app.name') }}
@endcomponent

View file

@ -2,34 +2,27 @@
<div class="container-fluid">
<div class="row">
<div class="col-3 d-none d-lg-block text-end">
@if(!empty($randomStampsFooter) && isset($randomStampsFooter[0]))
<img class="img-fluid" src="{{ asset($randomStampsFooter[0]->picture) }}"
title="{{ __($randomStampsFooter[0]->picture_title) }}" alt="{{ __($randomStampsFooter[0]->picture_alt) }}" />
@endif
<img class="img-fluid" src="{{ Vite::asset('resources/assets/images/layout/footer-left-logo.svg') }}"
alt="{{ __('Départ, Inspiration Asie') }}" />
</div>
<div class="col-12 col-lg-6 footer-header text-center">
<div class="h1 text-uppercase f-sheldon">{{ __('Envie d\'exploration') }}</div>
<div class="h2 text-uppercase f-sheldon">{{ __('Suivez-nous sur') }}</div>
</div>
<div class="col-3 d-none d-lg-block text-start">
@if(!empty($randomStampsFooter) && isset($randomStampsFooter[1]))
<img class="img-fluid" src="{{ asset($randomStampsFooter[1]->picture) }}"
title="{{ __($randomStampsFooter[1]->picture_title) }}" alt="{{ __($randomStampsFooter[1]->picture_alt) }}" />
@endif
<img class="img-fluid" src="{{ Vite::asset('resources/assets/images/layout/footer-right-logo.svg') }}"
alt="{{ __('Départ, Inspiration Italie') }}" />
</div>
</div>
<div class="row">
<div class="col text-center">
<a class="text-decoration-none" href="https://www.instagram.com/agis_explorateur_et_gastronome/"
title="{{ __('Nous suivre sur Instagram') }}" target="_blank">
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Instagram') }}" target="_blank">
@include('fo.partials.social-svg-instagram')
</a>
<a class="text-decoration-none" href="https://www.facebook.com/AgisGroupeLDC" title="{{ __('Nous suivre sur Facebook') }}"
target="_blank">
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Facebook') }}" target="_blank">
@include('fo.partials.social-svg-facebook')
</a>
<a class="text-decoration-none" href="https://www.linkedin.com/company/agis-groupe-ldc/mycompany/?viewAsMember=true"
title="{{ __('Nous suivre sur Linkedin') }}" target="_blank">
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Linkedin') }}" target="_blank">
@include('fo.partials.social-svg-linkedin')
</a>
</div>
@ -61,19 +54,19 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link text-uppercase @if (request()->routeIs('fo.ranges.*')) active @endif py-1" data-bs-toggle="tooltip"
<a class="nav-link text-uppercase @if (request()->routeIs('CHANGEME')) active @endif py-1" data-bs-toggle="tooltip"
href="{{ route('fo.ranges.index') }}" title="{{ __('Nos gammes') }}">
{{ __('Nos gammes') }}
</a>
</li>
<li class="nav-item">
<a class="nav-link text-uppercase @if (request()->routeIs('fo.aboutus.*')) active @endif py-1" data-bs-toggle="tooltip"
<a class="nav-link text-uppercase @if (request()->routeIs('CHANGEME')) active @endif py-1" data-bs-toggle="tooltip"
href="{{ route('fo.aboutus.show') }}" title="{{ __('Nous connaitre') }}">
{{ __('Nous connaitre') }}
</a>
</li>
<li class="nav-item">
<a class="nav-link text-uppercase cn-cookie-link py-1"
<a class="nav-link text-uppercase cn-cookie-link @if (request()->routeIs('CHANGEME')) active @endif py-1"
data-bs-toggle="tooltip" href="#" title="{{ __('Gestion des cookies') }}">
{{ __('cookie-notice.button_customize_cookies') }}
</a>

View file

@ -16,10 +16,6 @@
href="{{ route('fo.aboutus.show') }}" title="{{ __('Nous connaitre') }}">
{{ __('Nous connaitre') }}
</a>
<a class="nav-link display-5 fw-bold text-uppercase @if (request()->routeIs('fo.convictions')) active @endif" data-bs-toggle="tooltip"
href="{{ route('fo.convictions') }}" title="{{ __('Nos convictions') }}">
{{ __('Nos convictions') }}
</a>
<a class="nav-link display-5 fw-bold text-uppercase @if (request()->routeIs('fo.news.*')) active @endif" data-bs-toggle="tooltip"
href="{{ route('fo.news.index') }}" title="{{ __('Nos actualités') }}">
{{ __('Nos actualités') }}

File diff suppressed because one or more lines are too long

View file

@ -67,7 +67,7 @@
</div>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.email'))->ucFirst() }}*&nbsp;:</label>
<label class="mt-1">{{ Str::of(__('validation.attributes.email'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="email" value="{{ old('email') }}" required>
</fieldset>
</div>
@ -79,20 +79,20 @@
</div>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.address'))->ucFirst() }}*&nbsp;:</label>
<input class="form-control" name="address" value="{{ old('address') }}" required>
<label class="mt-1">{{ Str::of(__('validation.attributes.address'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="address" value="{{ old('address') }}">
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.postal_code'))->ucFirst() }}*&nbsp;:</label>
<input class="form-control" name="postal_code" type="number" value="{{ old('postal_code') }}" required>
<label class="mt-1">{{ Str::of(__('validation.attributes.postal_code'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="postal_code" type="number" value="{{ old('postal_code') }}">
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.city'))->ucFirst()->value() }}*&nbsp;:</label>
<input class="form-control" name="city" value="{{ old('city') }}" required>
<label class="mt-1">{{ Str::of(__('validation.attributes.city'))->ucFirst()->value() }}&nbsp;:</label>
<input class="form-control" name="city" value="{{ old('city') }}">
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
@ -126,17 +126,15 @@
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1" for="product_date_limit">
{{ Str::of(__('validation.custom.product_date_limit'))->ucFirst()->value() }}*&nbsp;:
<span class="text-body-secondary">{{ __('Ex : 25/08/2028') }}</span>
</label>
<input class="form-control" id="product_date_limit" name="product_date_limit" type="date"
<input class="form-control" id="product_date_limit" name="product_date_limit"
value="{{ old('product_date_limit') }}">
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1" for="product_barcode">
{{ Str::of(__('validation.custom.product_barcode'))->ucFirst()->value() }}*
{{ __('validation.custom.product_barcode_detail') }}&nbsp;:
{{ Str::of(__('validation.custom.product_barcode'))->ucFirst()->value() }}*&nbsp;:
</label>
<input class="form-control" id="product_barcode" name="product_barcode" type="number"
value="{{ old('product_barcode') }}">
@ -158,7 +156,7 @@
<span class="text-body-secondary">{{ __('Ex : 25/08/2028') }}</span>
</label>
<input class="form-control" id="product_date_consumption" name="product_date_consumption"
type="date" value="{{ old('product_date_consumption') }}">
value="{{ old('product_date_consumption') }}">
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
@ -190,14 +188,11 @@
</div>
</fieldset>
</div>
<p class="highlight white w-100 w-xl-fit m-0 mx-auto my-5 px-5 text-center">
{{ __('Laissez nous votre message, le service consommateurs vous répondra dans les plus brefs délais.') }}
</p>
</div>
<div class="col-12 mb-3 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start">
<label class="mt-1" for="message">
{{ Str::of(__('message'))->ucFirst()->value() }} {{ __('(entre 3 et 500 caractères)') }}*&nbsp;:
{{ Str::of(__('message'))->ucFirst()->value() }}*&nbsp;:
</label>
<textarea class="form-control" id="message" name="message" rows="6" required>{{ old('message') }}</textarea>
</fieldset>

View file

@ -9,8 +9,8 @@
<section class="convictions col-12 overflow-hidden">
<!-- TITLE CARD -->
<section class="title-card">
<div class="lh-sm my-2 px-5 py-2 text-center">
<h1 class="f-sheldon text-uppercase mx-auto w-fit">
<div class="my-2 px-5 py-2 text-center lh-sm">
<h1 class="f-sheldon text-uppercase w-fit mx-auto">
<span class="divide d-block mt-xl-5 mb-3 mt-4"></span>
{{ $staticPageModel->title }}
<span class="divide d-block mb-3 mt-3"></span>
@ -19,28 +19,27 @@
</section>
<section class="feed container my-4">
<h2 class="black-title f-readex-pro w-100 px-4 text-center text-white">
<h2 class="black-title text-white f-readex-pro w-100 text-center px-4">
{{ __('01 Bien nourrir') }}
</h2>
<div class="row">
<div class="col-12 col-lg-6 my-4">
<div class="d-flex align-items-center align-items-lg-start">
<p class="text-tertiary f-sheldon me-3">
{{ rtrim(rtrim(number_format($convictionpageModel->key_feed, 2, ',', ' '), '0'), ',') }}%</p>
<p class="f-readex-pro fw-bold pt-lg-3 pt-xl-4 text-justify">
{{ __('de nos approvisionnements en viande et volaille sont origine FRANCE') }}&nbsp;!</p>
<p class="text-tertiary f-sheldon me-3">{{ $convictionpageModel->key_feed }}%</p>
<p class="f-readex-pro fw-bold text-justify pt-lg-3 pt-xl-4">{{ __('de nos approvisionnements en viande et volaille sont origine FRANCE') }}&nbsp;!</p>
</div>
</div>
<div class="col-12 col-lg-6 my-4">
<div class="d-flex justify-content-center justify-content-lg-end flag">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/french-flag.png') }}"
title="{{ __('Drapeau français') }}" alt="{{ __('Dessin d\'un drapeau français entouré de coeurs') }}">
alt="{{ __('Dessin d\'un drapeau français entouré de coeurs') }}"
title="{{ __('Drapeau français') }}">
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-6">
<p class="fw-bold">
<p class="fw-bold">
{{ __('Les produits Traiteur étant de plus en plus présents dans l\'alimentation, nous renforçons la confiance des consommateurs par') }}&nbsp;:
</p>
<ul class="mb-0">
@ -62,8 +61,10 @@
</li>
</ul>
<div class="w-100 d-flex justify-content-center">
<img class="my-4" src="{{ Vite::asset('resources/assets/images/convictionpage/chicken.png') }}"
title="{{ __('Poulet qui picore') }}" alt="{{ __('Dessin d\'un poulet picorant des graines') }}">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/chicken.png') }}"
alt="{{ __('Dessin d\'un poulet picorant des graines') }}"
title="{{ __('Poulet qui picore') }}"
class="my-4">
</div>
</div>
</div>
@ -71,22 +72,22 @@
<section class="earth bg-agis-yellow">
<div class="container">
<h2 class="black-title f-readex-pro w-100 px-4 text-center text-white">
<h2 class="black-title text-white f-readex-pro w-100 text-center px-4">
{{ __('02 Respecter la Terre') }}
</h2>
</div>
<div class="row values">
<div class="col-12 col-md-6 mt-4">
<div class="row h-100 mb-3">
<div class="row mb-3 h-100">
<div class="col-6 ps-0">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/candle.png') }}" title="{{ __('Bougie') }}"
alt="{{ __('Dessin d\'une main tenant une bougie allumée') }}">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/candle.png') }}"
alt="{{ __('Dessin d\'une main tenant une bougie allumée') }}"
title="{{ __('Bougie') }}">
</div>
<div class="col-6">
<div class="h-100 d-flex justify-content-center align-items-center">
<div class="f-sheldon text-md-end mx-auto w-fit text-center">
<p class="value mb-0">
{{ rtrim(rtrim(number_format($convictionpageModel->key_earth_1, 2, ',', ' '), '0'), ',') }}%</p>
<div class="f-sheldon w-fit mx-auto text-center text-md-end">
<p class="value mb-0">{{ $convictionpageModel->key_earth_1 }}%</p>
<p class="fs-2 mb-0">{{ __('d\'énergie') }}</p>
<p class="f-readex-pro mb-0">{{ __('économisées') }}</p>
</div>
@ -99,9 +100,8 @@
<div class="row">
<div class="col-6">
<div class="h-100 d-flex justify-content-center align-items-center">
<div class="f-sheldon text-md-start mx-auto w-fit text-center">
<p class="value mb-0">
{{ rtrim(rtrim(number_format($convictionpageModel->key_earth_2, 2, ',', ' '), '0'), ',') }}%</p>
<div class="f-sheldon w-fit mx-auto text-center text-md-start">
<p class="value mb-0">{{ $convictionpageModel->key_earth_2 }}%</p>
<p class="fs-2 mb-0">{{ __('d\'eau') }}</p>
<p class="f-readex-pro mb-0">{{ __('économisées') }}</p>
</div>
@ -110,7 +110,8 @@
<div class="col-6">
<div class="pe-5">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/watercan.png') }}"
title="{{ __('Arrosoir') }}" alt="{{ __('Dessin d\'un arrosoir versant quelques gouttes') }}">
alt="{{ __('Dessin d\'un arrosoir versant quelques gouttes') }}"
title="{{ __('Arrosoir') }}">
</div>
</div>
</div>
@ -120,26 +121,26 @@
<div class="row">
<div class="col-12">
<div class="row justify-content-center align-items-end">
<div class="d-none d-lg-flex col-2 justify-content-end mb-2">
<img class="me-0" src="{{ Vite::asset('resources/assets/images/convictionpage/arrow2.png') }}"
<div class="d-none d-lg-flex col-2 mb-2 justify-content-end">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/arrow2.png') }}"
alt="{{ __('Flèche reliant l\'énergie économisée à la période') }}"
title="{{ __('Flèche vers la droite') }}"
alt="{{ __('Flèche reliant l\'énergie économisée à la période') }}">
class="me-0">
</div>
<div class="col-7 col-lg-4 text-center">
<p class="text-uppercase f-readex-pro fs-5 fw-bold bg-white-svg mb-0 px-2">{{ __('sur 3 ans') }}</p>
</div>
<div class="d-none d-lg-block col-2 mb-2">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/arrow3.png') }}"
title="{{ __('Flèche vers la gauche') }}" alt="{{ __('Flèche reliant l\'eau économisée à la période') }}">
alt="{{ __('Flèche reliant l\'eau économisée à la période') }}"
title="{{ __('Flèche vers la gauche') }}">
</div>
</div>
</div>
</div>
<div class="row mt-4 pb-4">
<div class="col-12 col-lg-6">
<p class="fw-bold">
{{ __('Nous conduisons des actions pluriannuelles pour conduire un développement durable et mieux préserver notre planète et ses ressources') }}&nbsp;:
</p>
<p class="fw-bold">{{ __('Nous conduisons des actions pluriannuelles pour conduire un développement durable et mieux préserver notre planète et ses ressources') }}&nbsp;:</p>
<ul class="mb-0">
<li>
{{ __('Développement de matériaux d\'emballages recyclables et durables') }}
@ -164,81 +165,73 @@
{{ __('Développement du photovoltaïque') }}
</li>
</ul>
<p class="fw-bold mt-5">
{{ __('Un générateur photovoltaïque d\'une puissance de 62 Kw est en service depuis 2009 sur le site d\'Avignon et a permis de réduire les émissions de CO2 de 158 T/an depuis son installation.') }}
</p>
<p class="fw-bold mt-5">{{ __('Un générateur photovoltaïque d\'une puissance de 62 Kw est en service depuis 2009 sur le site d\'Avignon et a permis de réduire les émissions de CO2 de 158 T/an depuis son installation.') }}</p>
</div>
</div>
</div>
</section>
{{-- VIVRE ENSEMBLE --}}
<section class="together container-fluid my-4">
<div class="container">
<h2 class="black-title f-readex-pro w-100 my-5 px-4 text-center text-white">
<h2 class="black-title text-white f-readex-pro w-100 text-center px-4 my-5">
{{ __('03 Vivre ensemble') }}
</h2>
<div class="row align-items-start mb-4">
<div class="row">
<div class="col-12 col-sm-6 col-lg-3 mb-3">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-2 text-center">
<div class="together-img-container h-100 d-flex align-items-center">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-5 text-center">
<div class="h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/balloons.png') }}"
title="{{ __('Ballons') }}" alt="{{ __('Dessin de 3 ballons') }}">
alt="{{ __('Dessin de 3 ballons') }}"
title="{{ __('Ballons') }}">
</div>
<p class="value text-uppercase fw-bold fs-4 mb-1 mt-3 px-3 text-white">
{{ rtrim(rtrim(number_format($convictionpageModel->key_together_1, 2, ',', ' '), '0'), ',') }}
{{ __('ans') }}</p>
<p>{{ __('d\'ancienneté moyenne') }}</p>
<p class="value text-uppercase fw-bold text-white fs-4 px-3 mt-3 mb-1">{{ $convictionpageModel->key_together_1 }} {{ __('ans')}}</p>
<p>{{ __('d\'ancienneté moyenne')}}</p>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mb-3">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-2 text-center">
<div class="together-img-container h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/cart.png') }}" title="{{ __('Caddie') }}"
alt="{{ __('Dessin d\'un caddie de course') }}">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-5 text-center">
<div class="h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/cart.png') }}"
alt="{{ __('Dessin d\'un caddie de course') }}"
title="{{ __('Caddie') }}">
</div>
<p class="value text-uppercase fw-bold fs-4 mb-1 mt-3 px-3 text-white">
{{ rtrim(rtrim(number_format($convictionpageModel->key_together_2, 2, ',', ' '), '0'), ',') }}€
</p>
<p>{{ __('consacrés au budget formation') }}</p>
<p class="value text-uppercase fw-bold text-white fs-4 px-3 mt-3 mb-1">{{ $convictionpageModel->key_together_2 }}€</p>
<p>{{ __('consacrés au budget formation')}}</p>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mb-3">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-2 text-center">
<div class="together-img-container h-100 d-flex align-items-center">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-5 text-center">
<div class="h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/contract.png') }}"
title="{{ __('Signature') }}" alt="{{ __('Dessin d\'un crayon laissant une trace') }}">
alt="{{ __('Dessin d\'un crayon laissant une trace') }}"
title="{{ __('Signature') }}">
</div>
<p class="value text-uppercase fw-bold fs-4 mb-1 mt-3 px-3 text-white">
{{ rtrim(rtrim(number_format($convictionpageModel->key_together_3, 2, ',', ' '), '0'), ',') }}
</p>
<p>{{ __('CDI signés sur 3 ans') }}</p>
<p class="value text-uppercase fw-bold text-white fs-4 px-3 mt-3 mb-1">{{ $convictionpageModel->key_together_3 }}</p>
<p>{{ __('CDI signés sur 3 ans')}}</p>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mb-3">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-2 text-center">
<div class="together-img-container h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/hands.png') }}" title="{{ __('Mains') }}"
alt="{{ __('Dessin de 2 mains liées') }}">
<div class="h-100 d-flex flex-column align-items-center justify-content-center f-readex-pro px-5 text-center">
<div class="h-100 d-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/hands.png') }}"
alt="{{ __('Dessin de 2 mains liées') }}"
title="{{ __('Mains') }}">
</div>
<p class="value text-uppercase fw-bold fs-4 mb-1 mt-3 px-3 text-white">
{{ rtrim(rtrim(number_format($convictionpageModel->key_together_4, 2, ',', ' '), '0'), ',') }}
</p>
<p>{{ __('Index égalité Homme/Femme') }}</p>
<p class="value text-uppercase fw-bold text-white fs-4 px-3 mt-3 mb-1">{{ $convictionpageModel->key_together_4 }}</p>
<p>{{ __('Index égalité Homme/Femme')}}</p>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-6">
<p class="fw-bold mb-4">
{{ __('Développer le potentiel humain avec des conditions de travail épanouissantes et sécurisées. Le bien-être et le bien-vivre au coeur de notre réussite.') }}
</p>
<p class="fw-bold mb-4">{{ __('Développer le potentiel humain avec des conditions de travail épanouissantes et sécurisées. Le bien-être et le bien-vivre au coeur de notre réussite.') }}</p>
<ul>
<li>
{{ __('Renforcer les valeurs fondamentales') }}&nbsp;:
</li>
</ul>
<p class="text-lg-start text-center">{{ __('Le respect - L\'écoute et l\'accompagnement') }}</p>
<p class="text-lg-start text-center">{{ __('Le partage des performances - La bienveillance') }}</p>
<p class="text-center text-lg-start">{{ __('Le respect - L\'écoute et l\'accompagnement') }}</p>
<p class="text-center text-lg-start">{{ __('Le partage des performances - La bienveillance') }}</p>
</div>
<div class="col-12 col-lg-6">
<ul>
@ -259,36 +252,35 @@
</div>
</div>
<div class="row">
<img class="mb-4 p-0" src="{{ Vite::asset('resources/assets/images/convictionpage/sun-with-clouds.png') }}"
<img src="{{ Vite::asset('resources/assets/images/convictionpage/sun-with-clouds.png') }}"
alt="{{ __('Dessin d\'un soleil avec queques nuages et une ligne en pointillés traversant') }}"
title="{{ __('Ciel') }}"
alt="{{ __('Dessin d\'un soleil avec queques nuages et une ligne en pointillés traversant') }}">
class="p-0 mb-4">
</div>
</section>
<section class="territory container-fluid my-5">
<div class="container">
<h2 class="black-title f-readex-pro w-100 my-5 px-4 text-center text-white">
<h2 class="black-title text-white f-readex-pro w-100 text-center px-4 my-5">
{{ __('04 Intégrer son territoire') }}
</h2>
{{-- </div> --}}
{{-- <div class="ms-0 ms-lg-5 ps-0 ps-lg-5 me-0 pe-0"> --}}
{{-- </div> --}}
{{-- <div class="ms-0 ms-lg-5 ps-0 ps-lg-5 me-0 pe-0"> --}}
<div class="row">
<div class="col-12 col-lg-6">
<div class="container">
<p class="text-tertiary text-uppercase text-lg-start f-sheldon fs-1 w-lg-75 text-center">
{{ number_format($convictionpageModel->key_territory, 0, ',', ' ') }}
{{ __('repas distribués gratuitement chaque année') }}</p>
<p class="f-readex-pro fw-bold">
{{ __('à différentes institutions comme des banques alimentaires, les restos du coeur...') }}</p>
<p class="text-tertiary text-uppercase text-center text-lg-start f-sheldon fs-1 w-lg-75">{{ number_format($convictionpageModel->key_territory, 0, ',', ' ') }} {{ __('repas distribués gratuitement chaque année')}}</p>
<p class="f-readex-pro fw-bold">{{ __('à différentes institutions comme des banques alimentaires, les restos du coeur...')}}</p>
</div>
</div>
<div class="col-12 col-lg-6 d-flex justify-content-end food pe-0">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/food.png') }}" title="{{ __('Nourriture') }}"
alt="{{ __('Dessin d\'une main tenant des tomates et des champignons') }}">
<div class="col-12 col-lg-6 d-flex justify-content-end pe-0 food">
<img src="{{ Vite::asset('resources/assets/images/convictionpage/food.png') }}"
alt="{{ __('Dessin d\'une main tenant des tomates et des champignons') }}"
title="{{ __('Nourriture') }}">
</div>
</div>
{{-- </div> --}}
{{-- <div class="container"> --}}
{{-- </div> --}}
{{-- <div class="container"> --}}
<div class="row mt-4">
<div class="col-12 col-lg-6">
<p class="fw-bold">{{ __('L\'entreprise, acteur local, participe à la vie de sa collectivité') }}&nbsp;:</p>

View file

@ -170,7 +170,7 @@
<p>
<span
class="second-paragraph lh-sm">{{ __('Et comme nous sommes curieux, ouverts sur le monde, nous avons à coeur de faire voyager vos papilles ;') }}</span>
{{ __('nous explorons et nous innovons avec toujours plus de créativité. En plus de notre offre traditionnelle, nous proposons une palette généreuse de plats exotiques inspirés du monde entier qui ont fait notre réputation : paella, nems, bo-bun, rouleaux de printemps.') }}
{{ __('nous explorons et nous innovons avec toujours plus de créativité. En plus de notre offre traditionnelle, nous proposons une palette généreuse de plats exotiques inspirés du monde entier qui ont fait notre réputation : paella, bo-bun, rouleaux de printemps.') }}
<br>
{{ __('A l\'apéritif du vendredi soir ou pour un dîner en semaine, en solo ou entre amis, le dépaysement est garanti !') }}
</p>
@ -185,7 +185,7 @@
<div class="row w-100 mx-auto">
<div class="col-12 col-md-6 p-0">
<div class="row w-100 justify-content-center mx-auto mb-4">
@foreach ($explorerpageModel->commitments()->where('published', true)->orderBy('order')->get() as $commitment)
@foreach ($explorerpageModel->commitments as $commitment)
<div class="col-4 d-flex justify-content-center p-2">
<img class="mx-auto" src="{{ asset($commitment->picture) }}" title="{{ $commitment->picture_title }}"
alt="{{ $commitment->picture_alt }}">

View file

@ -32,7 +32,7 @@
<div class="row w-100 mx-auto">
<div class="col-12 col-xl-6 p-xl-5 px-0">
<div class="d-flex flex-column justify-content-center align-items-start position-relative h-100 z-1 mb-5">
<h2 class="d-flex flex-column justify-content-center align-items-start text-uppercase position-relative w-75">
<h2 class="d-flex flex-column justify-content-center align-items-start text-uppercase position-relative">
<span class="f-readex-pro fs-6 fw-semibold">{{ __('au fil de l\'année') }}</span>
<span class="f-sheldon fs-1 mb-3 mt-1">{{ $seasonalSectionsModel->title }}</span>
</h2>
@ -50,7 +50,7 @@
<div class="description container px-4 py-5">
<h2 class="text-uppercase fs-1 f-sheldon text-center">{{ __('Agis c\'est') }}</h2>
<p class="description-subtitle lh-sm fs-6 fw-bold m-0 mx-auto px-4 text-center">
{{ $homepageModel->presentation_title }}</p>
{{ __('une palette généreuse de plats s\'inspirant du monde entier') }}</p>
<div class="row">
<div class="col-12 col-md-6 my-xl-0 mx-auto my-2">
<div class="w-75 mx-auto">
@ -62,7 +62,7 @@
<div class="col-12 col-md-6">
<div class="description-paragraph d-flex flex-column justify-content-center align-items-start h-100">
{!! clean($homepageModel->presentation_content) !!}
<a class="btn btn-primary fw-bold mt-1" href="{{ route('fo.explorer') }}">{{ __('> En savoir +') }}</a>
<button class="btn btn-primary fw-bold mt-1">{{ __('> En savoir +') }}</button>
</div>
</div>
</div>
@ -86,8 +86,7 @@
<p class="f-readex-pro m-0">
{{ \Carbon\Carbon::parse($newsModel->publish_at)->locale('fr_FR')->isoFormat('D MMM Y') }}</p>
<p class="fw-bold m-0 text-start">{{ $newsModel->title }}</p>
<a class="f-readex-pro text-dark"
href="{{ route('fo.news.show', $newsModel->slug) }}">{{ __('> Lire la suite') }}</a>
<a class="f-readex-pro text-dark" href="#">{{ __('> Lire la suite') }}</a>
</div>
</div>
</div>
@ -122,23 +121,20 @@
<div class="swiper-wrapper">
@foreach ($rangeModels as $key => $rangeModel)
<div class="swiper-slide">
<a href="{{ route('fo.ranges.show', $rangeModel->slug) }}">
<div
class="swiper-slide-content d-flex flex-column flex-xl-row justify-content-center justify-content-xl-end align-items-center m-xl-0 mx-auto">
<div
class="swiper-slide-content d-flex flex-column flex-xl-row justify-content-center justify-content-xl-end align-items-center m-xl-0 mx-auto">
<div
class="swiper-slide-content-details bg-agis-white @if (!$loop->first) swiper-slide-content-translate @endif position-relative z-1">
<p class="text-primary fs-5 f-readex-pro p-xl-2 p-xxl-4 text-xl-start m-0 mb-3 text-center">
{{ Str::of($rangeModel->title)->limit(30) }}
</p>
</div>
<img src="{{ asset($rangeModel->picture_thumbnail) }}"
title="{{ $rangeModel->picture_thumbnail_title }}" alt="{{ $rangeModel->picture_thumbnail_alt }}">
<div class="w-100 d-xl-none">
<a class="text-dark w-fit"
href="{{ route('fo.ranges.show', $rangeModel->slug) }}">{{ __('> En savoir +') }}</a>
</div>
class="swiper-slide-content-details bg-agis-white @if (!$loop->first) swiper-slide-content-translate @endif position-relative z-1">
<p class="text-primary fs-5 f-readex-pro p-xl-2 p-xxl-4 text-xl-start m-0 mb-3 text-center">
{{ Str::of($rangeModel->title)->limit(30) }}
</p>
</div>
</a>
<img src="{{ asset($rangeModel->picture_thumbnail) }}" title="{{ $rangeModel->picture_thumbnail_title }}"
alt="{{ $rangeModel->picture_thumbnail_alt }}">
<div class="w-100 d-xl-none">
<a class="text-dark w-fit" href="">{{ __('> En savoir +') }}</a>
</div>
</div>
</div>
@endforeach
</div>

View file

@ -16,7 +16,7 @@
</div>
<div class="col-12 mb-xl-5">
<p class="lh-sm m-0 mb-3 text-center">
{{ Str::of(__('Après plus de 30 ans de croissance soutenue par l\'innovation, intégrée au groupe familial français LDC, leader de l\'agro-alimentaire, AGIS est désormais une société comptant plus de 800 collaborateurs passionnés répartis sur ses 3 ateliers de production et une plateforme logistique.'))->ucFirst()->value() }}
{{ Str::of(__('Après plus de 30 ans de croissance soutenue par l\'innovation, intégrée au groupe familial français LDC, leader de l\'agro-alimentaire, AGIS est désormais une société comptant plus de 800 collaborateurs passionnés répartis sur ses 3 ateliers de production et une plateforme logistiques.'))->ucFirst()->value() }}
</p>
<div class="row justify-content-center">
<div class="col-12 col-xl-5 mb-3 text-center">

View file

@ -9,14 +9,10 @@
<section class="news position-relative bg-agis-grey pb-5">
@php
$data = [
'modelName' => 'actualité',
'itemModels' => json_decode(json_encode($newsModels)),
'newsModels' => json_decode(json_encode($newsModels)),
'categoryEnums' => \App\Enums\News\CategoryEnum::toArray(),
'routeFiltered' => 'fo.news.filtered',
'routeShow' => 'fo.news.show',
'showSelect' => true,
];
@endphp
<div class="items-list" data-json='@json($data)'></div>
<div class="news-list" data-json='@json($data)'></div>
</section>
@endsection

View file

@ -26,12 +26,12 @@
</div>
<article class="bg-agis-grey pt-5">
<div class="container">
<div class="mx-auto">
<div class="mx-auto text-center">
<div class="news-single-img bg-agis-white p-lg-5 p-md-4 mx-auto w-fit p-3 pt-0">
<img class="" src="{{ asset($newsModel->picture) }}" title="{{ Str::of($newsModel->picture_title)->ucFirst() }}"
alt="{{ Str::of($newsModel->picture_alt)->ucFirst() }}">
</div>
<div class="news-single-content mx-auto mt-3">
<div class="mx-auto mt-3">
<p class="fs-7 fw-semibold text-start">{{ $newsModel->subtitle }}</p>
<br>
{!! clean($newsModel->content) !!}
@ -40,14 +40,14 @@
<div class="row pb-5">
<div class="col text-center">
<p class="fs-3 mt-5">{{ __('Partager sur') }}</p>
<a class="text-decoration-none" href="https://www.facebook.com/sharer/sharer.php?u={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}&t={{ urlencode($newsModel->title) }}"
title="{{ __('Partager sur Facebook') }}"
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Instagram') }}"
target="_blank">
@include('fo.partials.social-svg-instagram')
</a>
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Facebook') }}" target="_blank">
@include('fo.partials.social-svg-facebook')
</a>
<a class="text-decoration-none" href="https://www.linkedin.com/sharing/share-offsite/?url={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}"
title="{{ __('Partager sur Linkedin') }}"
target="_blank">
<a class="text-decoration-none" href="#FIXME:Change this" title="{{ __('Nous suivre sur Linkedin') }}" target="_blank">
@include('fo.partials.social-svg-linkedin')
</a>
</div>

View file

@ -1,7 +1,7 @@
@extends('fo.layout')
@section('title', $productModel->seo_title ?? __('Fiche produit'))
@section('description', $productModel->seo_description ?? __('Fiche descriptive d\'un produit'))
@section('title', $product->seo_title ?? __('Fiche produit'))
@section('description', $product->seo_description ?? __('Fiche descriptive d\'un produit'))
@section('breadcrumb',
request()->route()->getName())
@ -10,34 +10,34 @@
<!-- TITLE CARD -->
<section class="title-card container-fluid position-relative overflow-hidden">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1"
src="{{ Vite::asset('resources/assets/images/global/bg-grey-desktop.png') }}" title="{{ __('Visuel servant de fond') }}"
alt="{{ __('fond gris') }}">
<div class="px-lg-5 lh-sm px-3 py-2 text-center">
src="{{ Vite::asset('resources/assets/images/global/bg-grey-desktop.png') }}" title="{{ __('Visuel servant de fond') }}"
alt="{{ __('fond gris') }}">
<div class="py-2 px-3 px-lg-5 text-center lh-sm">
<span class="divide d-block w-100 mt-lg-5 mb-3 mt-4"></span>
<h1 class="fs-1 f-sheldon text-uppercase">
{{ $productModel->title }}
{{ $product->title }}
</h1>
<span class="divide d-block w-100 mt-lg-3 mb-md-4 mb-1 mt-3"></span>
<span class="divide d-block w-100 mt-lg-3 mb-1 mb-md-4 mt-3"></span>
</div>
{{-- CARROUSEL image ambiance/packshot --}}
<div class="pictures mb-4 px-5">
<div class="swiper swiper-product-pictures h-100 d-lg-none overflow-hidden pb-3" id="swiper-product-pictures">
<div class="swiper swiper-product-pictures overflow-hidden pb-3 h-100 d-lg-none" id="swiper-product-pictures">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="swiper-slide-content d-flex justify-content-center align-items-center mx-auto px-3">
<img src="{{ asset($productModel->picture_ambiance) }}" title="{{ $productModel->picture_ambiance_title }}"
alt="{{ $productModel->picture_ambiance_alt }}">
<img src="{{ asset($product->picture_ambiance) }}"
title="{{ $product->picture_ambiance_title }}" alt="{{ $product->picture_ambiance_alt }}">
</div>
</div>
<div class="swiper-slide h-auto">
<div class="swiper-slide-content d-flex justify-content-center align-items-center h-100 mx-auto px-3">
<img src="{{ asset($productModel->picture_packshot) }}" title="{{ $productModel->picture_packshot_title }}"
alt="{{ $productModel->picture_packshot_alt }}">
<div class="swiper-slide-content d-flex justify-content-center align-items-center mx-auto px-3 h-100">
<img src="{{ asset($product->picture_packshot) }}"
title="{{ $product->picture_packshot_title }}" alt="{{ $product->picture_packshot_alt }}">
</div>
</div>
</div>
<div class="d-flex justify-content-evenly align-items-center d-lg-none mt-4 flex-row pb-4">
<div class="d-flex justify-content-evenly align-items-center d-lg-none pb-4 mt-4 flex-row">
<div class="swiper-button-prev rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
@ -48,35 +48,38 @@
</div>
</div>
</div>
<div class="d-none d-lg-flex justify-content-center ms-5 pb-5 pe-3 ps-5">
<img class="h-100 col-8 pb-5" src="{{ asset($productModel->picture_ambiance) }}"
title="{{ $productModel->picture_ambiance_title }}" alt="{{ $productModel->picture_ambiance_alt }}">
<img class="h-100 col-4 ms-4 mt-auto pb-5" src="{{ asset($productModel->picture_packshot) }}"
title="{{ $productModel->picture_packshot_title }}" alt="{{ $productModel->picture_packshot_alt }}">
<div class="d-none d-lg-flex justify-content-center ms-5 ps-5 pe-3 pb-5">
<img src="{{ asset($product->picture_ambiance) }}"
title="{{ $product->picture_ambiance_title }}"
alt="{{ $product->picture_ambiance_alt }}"
class="h-100 col-8 pb-5">
<img src="{{ asset($product->picture_packshot) }}"
title="{{ $product->picture_packshot_title }}"
alt="{{ $product->picture_packshot_alt }}"
class="h-100 col-4 pb-5 ms-4 mt-auto">
</div>
</div>
{{-- DESCRIPTION --}}
<div class="text-lg-center col-12 col-lg-9 mx-lg-auto px-3 text-justify">{!! clean($productModel->description) !!}</div>
<div class="text-justify text-lg-center col-12 col-lg-9 px-3 mx-lg-auto">{!! clean($product->description) !!}</div>
{{-- PICTOS --}}
@if (!empty($productModel->commitments))
<div class="pictos col-12 col-lg-8 mx-auto px-3 pb-5">
<span class="divide d-block w-100 mt-lg-5 mb-lg-4 mb-2 mt-4"></span>
<div class="row justify-content-center px-lg-4">
@foreach ($productModel->commitments as $commitment)
@if ($commitment->published)
<div class="col-3">
<div class="w-100 d-flex justify-content-center">
<img src="{{ asset($commitment->picture) }}" title="{{ $commitment->picture_title }}"
alt="{{ $commitment->picture_alt }}">
</div>
</div>
@endif
@endforeach
</div>
<span class="divide d-block w-100 mt-lg-4 mb-3 mt-2"></span>
@if (!empty($product->commitments))
<div class="pictos px-3 pb-5 col-12 col-lg-8 mx-auto">
<span class="divide d-block w-100 mt-lg-5 mb-2 mb-lg-4 mt-4"></span>
<div class="row justify-content-center px-lg-4">
@foreach ($product->commitments as $commitment)
<div class="col-3">
<div class="w-100 d-flex justify-content-center">
<img src="{{ asset($commitment->picture) }}"
alt="{{ $commitment->picture_alt }}"
title="{{ $commitment->picture_title }}">
</div>
</div>
@endforeach
</div>
<span class="divide d-block w-100 mt-lg-4 mb-3 mt-2"></span>
</div>
@endif
</section>
@ -84,47 +87,44 @@
<div class="row px-3">
<div class="col-12 col-lg-6">
{{-- COOKING ADVICE --}}
<section class="row">
<h2 class="green-title f-readex-pro fs-6 w-100 px-4 py-2 text-white">{{ __('Conseils de Réchauffage') }}</h2>
<div class="col-12 mt-4">
<img class="picto-img float-start me-3 mt-3" src="{{ Vite::asset($productModel->cooking_mode->picture()) }}"
title="{{ $productModel->cooking_mode->label() }}" alt="{{ $productModel->cooking_mode->alt() }}">
<div class="cooking-advice text-justify">{!! clean($productModel->cooking_advice) !!}</div>
</div>
</section>
<h2 class="green-title f-readex-pro text-white fs-6 px-4 py-2 w-100">{{ __('Conseils de Réchauffage') }}</h2>
<div class="col-12 mt-4">
<img src="{{ Vite::asset($product->cooking_mode->picture()) }}"
alt="{{ $product->cooking_mode->alt() }}"
title="{{ $product->cooking_mode->label() }}"
class="picto-img float-start me-3 mt-3">
<div class="text-justify">{!! clean($product->cooking_advice) !!}</div>
</div>
{{-- INGREDIENTS --}}
<section class="row">
<h2 class="green-title f-readex-pro fs-6 w-100 mt-5 px-4 py-2 text-white">{{ __('Ingrédients') }}</h2>
<div class="col-12">
<div class="text-justify">{!! clean($productModel->ingredients) !!}</div>
</div>
</section>
<h2 class="green-title f-readex-pro text-white fs-6 px-4 py-2 w-100 mt-5">{{ __('Ingrédients') }}</h2>
<div class="col-12">
<div class="text-justify">{!! clean($product->ingredients) !!}</div>
</div>
</div>
<div class="col-12 col-lg-6 h-auto">
<div class="h-100 d-flex flex-column justify-content-between">
<div class="h-50 d-none d-lg-flex align-items-center justify-content-center">
<img src="{{ asset($productModel->range->picture_productsheet) }}"
title="{{ $productModel->range->picture_productsheet_alt }}"
alt="{{ $productModel->range->picture_productsheet_title }}">
<div class="h-50 d-none d-lg-flex align-items-center">
<img src="{{ Vite::asset('resources/assets/images/products/leafs-and-seeds.png') }}"
alt="Dessins de feuilles et de graines éparpillées"
title="Décoration fiche produit">
</div>
{{-- NUTRITIONNAL VALUES --}}
@php
$nutrionnal_values = json_decode($productModel->nutritionnal_values);
$nutrionnal_values = json_decode($product->nutritionnal_values);
@endphp
<table class="table-bordered f-readex-pro mt-4 table">
<table class="table table-bordered mt-4 f-readex-pro">
<thead>
<tr class="table-dark">
<th class="text-uppercase ps-sm-5 py-xl-3 text-white">{{ __('Valeurs nutritionnelles') }}</th>
<th class="py-xl-3 text-center text-white"><span class="text-uppercase">{{ __('POUR') }}</span>
{{ __('100g') }}</th>
<th class="text-uppercase text-white ps-sm-5 py-xl-3">{{ __('Valeurs nutritionnelles') }}</th>
<th class="text-white text-center py-xl-3"><span class="text-uppercase">{{ __('POUR') }}</span> {{ __('100g') }}</th>
</tr>
</thead>
<tbody>
@foreach ($nutrionnal_values as $line)
<tr class="table-secondary">
<td class="text-dark ps-sm-5">{{ $line->label }}</td>
<td class="text-dark text-center">{{ $line->value }}</td>
</tr>
<tr class="table-secondary">
<td class="text-dark ps-sm-5">{{ $line->label }}</td>
<td class="text-dark text-center">{{ $line->value }}</td>
</tr>
@endforeach
</tbody>
</table>
@ -134,54 +134,49 @@
</section>
@if (count($otherProductModels))
<section class="discover container-fluid position-relative mb-4 py-5">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1"
<section class="discover container-fluid position-relative py-5 mb-4">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1"
src="{{ Vite::asset('resources/assets/images/global/bg-grey-desktop.png') }}" title="{{ __('Visuel servant de fond') }}"
alt="{{ __('fond gris') }}">
<h2 class="text-primary text-uppercase f-sheldon w-100 pt-xl-4 mb-5 pt-3 text-center">
{{ __('Découvrez nos produits') }}
</h2>
{{-- CARROUSEL produits même gamme mais ordre aléatoire --}}
<div class="other-products px-xl-5 mx-xl-5 px-3">
<div class="swiper swiper-other-products w-xl-100 mx-xl-0 overflow-hidden" id="swiper-other-products">
<div class="swiper-wrapper">
@foreach ($otherProductModels as $otherProduct)
<div class="swiper-slide">
<div
class="swiper-slide-content d-flex flex-column justify-content-center align-items-center pb-xl-5 w-xl-75 mx-auto px-3 pt-5">
<a href="{{ route('fo.products.show', $otherProduct->slug) }}">
<img class="" src="{{ asset($otherProduct->picture_ambiance) }}"
title="{{ $otherProduct->picture_ambiance_title }}"
alt="{{ $otherProduct->picture_ambiance_alt }}">
</a>
<div class="w-100 d-xl-none">
<a class="w-fit"
href="{{ route('fo.products.show', $otherProduct->slug) }}">{{ __('> En savoir +') }}</a>
</div>
</div>
</div>
@endforeach
</div>
@if (count($otherProductModels) > 1)
<div
class="navigation d-flex justify-content-evenly justify-content-xl-between align-items-center p-xl-4 mb-2 mt-3 flex-row p-0">
<div class="swiper-button-prev rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
</div>
<div class="swiper-button-next rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
<h2 class="text-primary text-uppercase f-sheldon text-center w-100 pt-3 pt-xl-4 mb-5">
{{ __('Découvrez nos produits') }}
</h2>
{{-- CARROUSEL produits même gamme mais ordre aléatoire --}}
<div class="other-products px-3 px-xl-5 mx-xl-5">
<div class="swiper swiper-other-products overflow-hidden w-xl-100 mx-xl-0" id="swiper-other-products">
<div class="swiper-wrapper">
@foreach ($otherProductModels as $otherProduct)
<div class="swiper-slide">
<div class="swiper-slide-content d-flex flex-column justify-content-center align-items-center mx-auto px-3 pt-5 pb-xl-5 w-xl-75">
<img src="{{ asset($otherProduct->picture_ambiance) }}"
title="{{ $otherProduct->picture_ambiance_title }}"
alt="{{ $otherProduct->picture_ambiance_alt }}"
class="">
<div class="w-100 d-xl-none">
<a class="w-fit" href="{{ route('fo.products.show', ['publishedProduct' => $otherProduct]) }}">{{ __('> En savoir +') }}</a>
</div>
</div>
@endif
</div>
@endforeach
</div>
@if (count($otherProductModels) > 1)
<div class="navigation d-flex justify-content-evenly justify-content-xl-between align-items-center p-xl-4 mb-2 mt-3 flex-row p-0">
<div class="swiper-button-prev rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
</div>
<div class="swiper-button-next rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
</div>
</div>
@endif
</div>
<div class="pb-4">
<a class="btn btn-primary d-none d-xl-block mx-auto my-4 w-fit"
href="{{ route('fo.ranges.index') }}">{{ __('> Voir toutes nos gammes') }}</a>
</div>
</section>
</div>
<div class="pb-4">
<a class="btn btn-primary d-none d-xl-block mx-auto my-4 w-fit" href="#">{{ __('> Voir toutes nos gammes') }}</a>
</div>
</section>
@endif
</section>
@endsection

View file

@ -28,16 +28,72 @@
title="{{ Str::of(__('le plaisir de cuisiner'))->ucFirst() }}" alt="{{ Str::of(__('femme cuisine'))->ucFirst() }}">
</div>
</div>
<div class="ranges-flexwrap d-none d-xl-flex justify-content-center align-items-center flex-row flex-wrap">
@foreach ($rangeModels as $rangeModel)
<div class="col-4 mb-5">
<div class="card position-relative rounded-0 bg-agis-white mx-auto border-0 bg-transparent p-4">
<a class="text-decoration-none stretched-link" href="{{ route('fo.ranges.show', $rangeModel->slug) }}">
<div class="card-header d-flex justify-content-center align-items-center border-0 bg-transparent p-0">
<p class="text-dark f-readex-pro m-0 p-0 text-center">
{{ Str::of($rangeModel->title)->limit(35) }}
</p>
</div>
<div class="card-body position-relative p-0">
<div
class="position-absolute w-100 h-100 visibility-hidden text-dark start-0 top-0 bg-white bg-opacity-75 p-2 opacity-0">
{{ Str::of($rangeModel->tagline)->limit(100) }}
</div>
<img src="{{ asset($rangeModel->picture_thumbnail) }}"
title="{{ $rangeModel->picture_thumbnail_title }}" alt="{{ $rangeModel->picture_thumbnail_alt }}">
</div>
</a>
</div>
</div>
@endforeach
</div>
</div>
<div class="ranges-swiper container-fluid position-relative d-xl-none px-4">
<div class="swiper swiper-ranges overflow-hidden py-4" id="swiper-ranges">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1 d-xl-none"
src="{{ Vite::asset('resources/assets/images/global/bg-white-desktop.png') }}"
title="{{ __('Visuel servant de fond') }}" alt="{{ __('fond blanc') }}">
<div class="swiper-wrapper">
@foreach ($rangeModels as $key => $rangeModel)
<div class="swiper-slide">
<div class="swiper-slide-content d-flex flex-column justify-content-center align-items-center m-xl-0 mx-auto">
<div
class="swiper-slide-content-details @if (!$loop->first) swiper-slide-content-translate @endif position-relative z-1">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1 d-none d-xl-block"
src="{{ Vite::asset('resources/assets/images/global/bg-white-desktop.png') }}"
title="{{ __('Visuel servant de fond') }}" alt="{{ __('fond blanc') }}">
<p class="text-primary fs-5 f-readex-pro p-xl-2 p-xxl-4 m-0 mb-3 text-center">
{{ Str::of($rangeModel->title)->limit(30) }}
</p>
</div>
<img src="{{ asset($rangeModel->picture_thumbnail) }}" title="{{ $rangeModel->picture_thumbnail_title }}"
alt="{{ $rangeModel->picture_thumbnail_alt }}">
<div class="w-100 d-xl-none mt-2">
<p class="m-0">{{ Str::of($rangeModel->tagline)->limit(100) }}</p>
<a class="text-dark fw-bold w-fit"
href="{{ route('fo.ranges.show', $rangeModel->slug) }}">{{ __('> En savoir +') }}</a>
</div>
</div>
</div>
@endforeach
</div>
<div
class="navigation d-flex justify-content-evenly justify-content-xl-between align-items-center p-xl-4 mb-2 mt-3 flex-row p-0">
<div class="swiper-button-prev rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
</div>
<div class="swiper-button-next rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
</div>
</div>
</div>
</div>
@php
$data = [
'modelName' => 'gamme',
'itemModels' => json_decode(json_encode($rangeModels)),
'routeFiltered' => 'fo.ranges.filtered',
'routeShow' => 'fo.ranges.show',
];
@endphp
<div class="items-list" data-json='@json($data)'></div>
</div>
<p class="lh-sm fw-bold my-4 px-5 text-center">{{ __('Retrouvez-nous au rayon traiteur traditionnel de vos magasins préférés.') }}</p>
</section>

View file

@ -31,25 +31,72 @@
alt="{{ Str::of($rangeModel->picture_title)->ucFirst() }}">
</div>
</div>
@if (count($productModels))
<div class="col-12 mt-xl-5">
<p class="highlight black f-readex-pro mx-xl-auto m-0 px-3 text-white">
{{ Str::of(__('Quelques-unes de nos recettes...'))->ucFirst() }}
</p>
<div class="col-12 my-xl-5">
<p class="highlight black f-readex-pro mx-xl-auto m-0 px-3 text-white">
{{ Str::of(__('Quelques-unes de nos recettes...'))->ucFirst() }}
</p>
</div>
<div class="col-12">
<div class="ranges-swiper position-relative d-xl-none">
<div class="swiper swiper-ranges overflow-hidden py-4" id="swiper-ranges">
<img class="position-absolute top-50 start-50 translate-middle w-100 h-100 z-n1 d-xl-none"
src="{{ Vite::asset('resources/assets/images/global/bg-white-desktop.png') }}"
title="{{ __('Visuel servant de fond') }}" alt="{{ __('fond blanc') }}">
<div class="swiper-wrapper">
@foreach ($productModels as $productModel)
<div class="swiper-slide">
<div class="swiper-slide-range m-xl-0 mx-auto">
<img src="{{ asset($productModel->picture_thumbnail) }}"
title="{{ $productModel->picture_thumbnail_title }}"
alt="{{ $productModel->picture_thumbnail_alt }}">
<p class="text-dark fw-bold m-0 mt-2">
{{ $productModel->title }}
</p>
<p class="text-dark m-0">
{{ $productModel->subtitle }}
</p>
<div class="w-100 d-xl-none">
<a class="fw-bold text-dark w-fit" href="#">{{ __('> En savoir +') }}</a>
</div>
</div>
</div>
@endforeach
</div>
<div
class="navigation d-flex justify-content-evenly justify-content-xl-between align-items-center p-xl-4 mb-2 mt-3 flex-row p-0">
<div class="swiper-button-prev rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (gauche)') }}" alt="{{ __('flèche vers la gauche') }}">
</div>
<div class="swiper-button-next rounded-circle" role="button">
<img src="{{ Vite::asset('resources/assets/images/global/btn-arrow.png') }}"
title="{{ __('Navigation du slider (droite)') }}" alt="{{ __('flèche vers la droite') }}">
</div>
</div>
</div>
</div>
<div class="col-12">
@php
$data = [
'modelName' => 'produit',
'itemModels' => json_decode(json_encode($productModels)),
'range_id' => $rangeModel->id,
'routeFiltered' => 'fo.products.filtered',
'routeShow' => 'fo.products.show',
];
@endphp
<div class="items-list" data-json='@json($data)'></div>
</div>
<div class="col-12">
<div class="d-none d-xl-flex row gx-5 justify-content-start align-items-start flex-row flex-wrap">
@foreach ($productModels as $productModel)
<div class="col-4 mb-5">
<div class="card mx-auto border-0">
<a class="text-decoration-none stretched-link" href="{{ route('fo.products.show', $productModel) }}">
<img class="card-img-top rounded-0" src="{{ asset($productModel->picture_thumbnail) }}"
title="{{ $productModel->picture_thumbnail_title }}"
alt="{{ $productModel->picture_thumbnail_alt }}">
<div class="card-body p-0">
<p class="text-dark card-title fw-bold my-2">{{ $productModel->title }}</p>
<p class="text-dark card-text m-0">
{{ $productModel->subtitle }}
</p>
</div>
</a>
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
</div>
</section>

View file

@ -8,13 +8,5 @@
filtered: "{{ route('fo.news.filtered') }}",
show: "{{ route('fo.news.show', ['slug' => 'SLUG']) }}"
},
ranges: {
filtered: "{{ route('fo.ranges.filtered') }}",
show: "{{ route('fo.ranges.show', ['slug' => 'SLUG']) }}"
},
products: {
filtered: "{{ route('fo.products.filtered') }}",
show: "{{ route('fo.products.show', ['slug' => 'SLUG']) }}"
},
};
</script>

View file

@ -36,7 +36,7 @@ Route::prefix('bo')
]
);
});
Route::middleware('admin-secure', 'auth:backend')->group(function () {
Route::middleware('auth:backend')->group(function () {
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
// * USERS.

View file

@ -9,22 +9,17 @@ use Illuminate\Support\Facades\Route;
Route::middleware(['throttle:credentials'])
->name('fo.')
->group(function () {
Route::middleware(['local-development'])->group(function () {
Route::view('/bs-demo', 'fo.pages.bs-demo')->name('bs-demo');
});
Route::get('/', [StaticPageController::class, 'homepage'])->name('homepage');
Route::get('/explorateur-et-gastronome', [StaticPageController::class, 'explorer'])->name('explorer');
Route::get('/nos-convictions', [StaticPageController::class, 'convictions'])->name('convictions');
Route::view('/bs-demo', 'fo.pages.bs-demo')->name('bs-demo');
// * RANGES
Route::get('/gammes', [RangeController::class, 'index'])->name('ranges.index');
Route::get('/gammes/filtered', [RangeController::class, 'rangesFiltered'])->name('ranges.filtered');
Route::get('/gamme/{slug}', [RangeController::class, 'show'])->name('ranges.show');
Route::get('/gammes/{slug}', [RangeController::class, 'show'])->name('ranges.show');
// * PRODUCTS
Route::get('/produits/filtered', [ProductController::class, 'productsFiltered'])->name('products.filtered');
Route::get('/produits/{slug}', [ProductController::class, 'show'])->name('products.show');
Route::get('/produits/{publishedProduct:slug}', [ProductController::class, 'show'])->name('products.show');
// * RANGES
Route::get('/rejoignez-nous', [StaticPageController::class, 'joinus'])->name('joinus.show');