Merge branch 'trunk'

This commit is contained in:
Vincent BRIDIER 2024-10-08 10:05:56 +02:00
commit 9c139005e4
18 changed files with 1293 additions and 1301 deletions

View file

@ -31,6 +31,7 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
MAIL_CONTACTFORM_RECEIVER=
MAIL_CONTACTFORM_CUSTOMER_SERVICE_RECEIVER=
# Sentry
SENTRY_LARAVEL_DSN=
@ -44,5 +45,5 @@ GOOGLE_RECAPTCHA_PUBLIC=
GOOGLE_RECAPTCHA_PRIVATE=
GOOGLE_RECAPTCHA_VERSION=
# Admin secure
LDC_WEB_API_KEY=
# Admin secure
LDC_WEB_API_KEY=

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Fo;
use App\Enums\Contact\ObjectEnum;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\ContactRequest;
@ -103,14 +104,19 @@ class StaticPageController extends Controller
}
/**
* Display a listing of the resource.
* Handle contactForm Request
*
* @param \App\Http\Requests\Fo\ContactRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function contactForm(ContactRequest $request): \Illuminate\Http\RedirectResponse
{
$receivers = \config('mail.contactform.receiver');
if ($request->object === strval(ObjectEnum::customerService->value())) {
$receivers = \config('mail.contactform.customerService');
} else {
$receivers = \config('mail.contactform.receiver');
}
foreach ($receivers as $email) {
Mail::to($email)->send(new SendContactMail((object)$request->validated()));
}
@ -180,7 +186,7 @@ class StaticPageController extends Controller
}
/**
* Display a listing of the resource.
* Handle joinusForm Request
*
* @param \App\Http\Requests\Fo\JoinusRequest $request
* @return \Illuminate\Http\RedirectResponse

View file

@ -60,6 +60,7 @@ class SecureHeaders
'https://yl.s-web.fr',
]) . ';',
"img-src 'self' data: blob: " . implode(' ', [
'https://yl.s-web.fr',
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : ''
]) . ';',
@ -97,6 +98,7 @@ class SecureHeaders
"$scheme://www.google-analytics.com",
'https://www.google.com/recaptcha/',
'https://www.gstatic.com/recaptcha/',
'https://yl.s-web.fr',
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : '',
]) . ';'
@ -107,8 +109,11 @@ class SecureHeaders
implode(' ', $cspPolicies) . $reportUri
);
$response->headers->set('Feature-Policy', \implode(',', [
'fullscreen', 'accelerometer', 'encrypted-media',
'gyroscope', 'picture-in-picture'
'fullscreen',
'accelerometer',
'encrypted-media',
'gyroscope',
'picture-in-picture'
]) . ';');
return $response;
}

View file

@ -20,10 +20,6 @@ class ContactRequest extends FormRequest
*/
protected function prepareForValidation()
{
$this->merge([
'accept_rules' => $this->boolean('accept_rules'),
'send_data' => $this->boolean('send_data'),
]);
$this->mergePicture('file');
}
@ -50,13 +46,13 @@ class ContactRequest extends FormRequest
'city' => 'required|string|between:3,255',
'object' => ['required', new Enum(ObjectEnum::class)],
'message' => 'required|string|between:3,500',
'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',
'string',
'between:3,255',
'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -69,7 +65,8 @@ class ContactRequest extends FormRequest
}
],
'product_date_limit' => [
'required', 'date',
'required',
'date',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -82,7 +79,9 @@ class ContactRequest extends FormRequest
}
],
'product_barcode' => [
'numeric', 'min:0', 'required',
'numeric',
'min:0',
'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -95,7 +94,9 @@ class ContactRequest extends FormRequest
}
],
'product_lot' => [
'numeric', 'min:0', 'required',
'numeric',
'min:0',
'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -108,7 +109,8 @@ class ContactRequest extends FormRequest
}
],
'product_date_consumption' => [
'required', 'date',
'required',
'date',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -121,7 +123,9 @@ class ContactRequest extends FormRequest
}
],
'product_location' => [
'string', 'between:3,255', 'required',
'string',
'between:3,255',
'required',
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
function ($attribute, $value, $fail) {
if ($this->get("object") != ObjectEnum::customerService->value()) {
@ -198,8 +202,6 @@ class ContactRequest extends FormRequest
'product_date_consumption' => trans('validation.custom.product_date_consumption'),
'product_location' => trans('validation.custom.product_location'),
'message' => trans('validation.attributes.message'),
'accept_rules' => trans('validation.custom.accept_rules'),
'send_data' => trans('validation.custom.send_data'),
'file' => trans('validation.custom.file'),
];
}

View file

@ -95,8 +95,6 @@ class SendContactMail extends Mailable
* @property string $product_lot
* @property string $product_date_consumption
* @property string $product_location
* @property boolean $accept_rules
* @property boolean $send_data
* @property \Illuminate\Http\UploadedFile $file
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
*/

1837
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -97,7 +97,8 @@ return [
],
'contactform' => [
'receiver' => explode(',', env('MAIL_CONTACTFORM_RECEIVER', 'hello@example.com'))
'receiver' => explode(',', env('MAIL_CONTACTFORM_RECEIVER', 'hello@example.com')),
'customerService' => explode(',', env('MAIL_CONTACTFORM_CUSTOMER_SERVICE_RECEIVER'))
],
/*

View file

@ -1,4 +1,3 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
@ -8,7 +7,7 @@ data:
APP_ENV: "${APP_APP_ENV}"
APP_KEY: "${APP_APP_KEY}"
APP_DEBUG: "${APP_APP_DEBUG}"
APP_URL: "https://www.${APP_DOMAIN}"
APP_URL: "https://${REDIRECT}${APP_DOMAIN}"
LOG_CHANNEL: "k8s"
DB_HOST: "mariadb.common-services"
DB_DATABASE: "${APP_DB_DATABASE}"
@ -22,6 +21,7 @@ data:
MAIL_FROM_ADDRESS: "${APP_MAIL_FROM_ADDRESS}"
MAIL_FROM_NAME: "${APP_APP_NAME}"
MAIL_CONTACTFORM_RECEIVER: "${APP_MAIL_CONTACTFORM_RECEIVER}"
MAIL_CONTACTFORM_CUSTOMER_SERVICE_RECEIVER: "${APP_MAIL_CONTACTFORM_CUSTOMER_SERVICE_RECEIVER}"
LDC_WEB_API_KEY: "${APP_LDC_WEB_API_KEY}"
GOOGLE_RECAPTCHA_PRIVATE: "${APP_GOOGLE_RECAPTCHA_PRIVATE}"
GOOGLE_RECAPTCHA_PUBLIC: "${APP_GOOGLE_RECAPTCHA_PUBLIC}"
@ -37,7 +37,7 @@ metadata:
spec:
storageClassName: "csi-cinder-classic"
accessModes:
- ReadWriteOnce
- ReadWriteOnce
resources:
requests:
storage: $APP_PVC_SIZE
@ -58,26 +58,25 @@ spec:
app: ${CI_PROJECT_PATH_SLUG}-app
spec:
containers:
- name: ${CI_PROJECT_PATH_SLUG}-container
image: $IMAGE_TAG
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
- name: ${CI_PROJECT_PATH_SLUG}-container
image: $IMAGE_TAG
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
imagePullSecrets:
- name: docker-registry-credentials
- name: docker-registry-credentials
securityContext:
runAsUser: 33
runAsGroup: 33
fsGroup: 33
fsGroupChangePolicy: "OnRootMismatch"
volumes:
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
---
apiVersion: v1
@ -88,8 +87,8 @@ spec:
selector:
app: ${CI_PROJECT_PATH_SLUG}-app
ports:
- port: 80
targetPort: 443
- port: 80
targetPort: 443
---
apiVersion: traefik.io/v1alpha1
@ -98,17 +97,16 @@ metadata:
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
spec:
entryPoints:
- web
- websecure
- web
- websecure
routes:
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
kind: Rule
services:
- name: ${CI_PROJECT_PATH_SLUG}-service
port: 80
middlewares:
- name: redirect-no-www-to-www
namespace: common-services
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
kind: Rule
services:
- name: ${CI_PROJECT_PATH_SLUG}-service
port: 80
middlewares:
- name: redirect-no-www-to-www
tls:
secretName: ${CRT_TLS_NAME}

184
package-lock.json generated
View file

@ -12,7 +12,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.5",
"@ldc-web/cookie-notice": "^4.1.0",
"@ldc-web/cookie-notice": "^6.0.3",
"@sipec/vue3-tags-input": "^3.0.4",
"@types/bootstrap": "^5.2.7",
"@types/node": "^20.8.2",
@ -1050,9 +1050,9 @@
"dev": true
},
"node_modules/@ldc-web/cookie-notice": {
"version": "4.1.0",
"resolved": "https://lab.s-web.fr/api/v4/projects/50/packages/npm/@ldc-web/cookie-notice/-/@ldc-web/cookie-notice-4.1.0.tgz",
"integrity": "sha1-bhDGIDjM6T0uMaovPpEc2hjTa+4=",
"version": "6.0.3",
"resolved": "https://lab.s-web.fr/api/v4/projects/50/packages/npm/@ldc-web/cookie-notice/-/@ldc-web/cookie-notice-6.0.3.tgz",
"integrity": "sha1-mW2DD+8ipWkmvKhZ3m9h5wemAHI=",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {
@ -1144,17 +1144,6 @@
"@types/json-schema": "*"
}
},
"node_modules/@types/eslint-scope": {
"version": "3.7.7",
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@ -2013,9 +2002,9 @@
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
"integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
"integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
"dev": true,
"peer": true,
"dependencies": {
@ -2038,9 +2027,9 @@
"peer": true
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
"integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
"integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
"dev": true,
"peer": true
},
@ -2064,16 +2053,16 @@
"peer": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
"integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
"integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
"@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/wasm-gen": "1.11.6"
"@webassemblyjs/wasm-gen": "1.12.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
@ -2104,30 +2093,30 @@
"peer": true
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
"integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
"integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
"@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/helper-wasm-section": "1.11.6",
"@webassemblyjs/wasm-gen": "1.11.6",
"@webassemblyjs/wasm-opt": "1.11.6",
"@webassemblyjs/wasm-parser": "1.11.6",
"@webassemblyjs/wast-printer": "1.11.6"
"@webassemblyjs/helper-wasm-section": "1.12.1",
"@webassemblyjs/wasm-gen": "1.12.1",
"@webassemblyjs/wasm-opt": "1.12.1",
"@webassemblyjs/wasm-parser": "1.12.1",
"@webassemblyjs/wast-printer": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
"integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
"integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
"@webassemblyjs/leb128": "1.11.6",
@ -2135,26 +2124,26 @@
}
},
"node_modules/@webassemblyjs/wasm-opt": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
"integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
"integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
"@webassemblyjs/wasm-gen": "1.11.6",
"@webassemblyjs/wasm-parser": "1.11.6"
"@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/wasm-gen": "1.12.1",
"@webassemblyjs/wasm-parser": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
"integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
"integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-api-error": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
@ -2163,13 +2152,13 @@
}
},
"node_modules/@webassemblyjs/wast-printer": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
"integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
"integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/ast": "1.12.1",
"@xtuc/long": "4.2.2"
}
},
@ -2199,10 +2188,10 @@
"node": ">=0.4.0"
}
},
"node_modules/acorn-import-assertions": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"node_modules/acorn-import-attributes": {
"version": "1.9.5",
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
"integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
"dev": true,
"peer": true,
"peerDependencies": {
@ -2473,12 +2462,12 @@
}
},
"node_modules/axios": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.4",
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@ -2543,12 +2532,12 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -3035,9 +3024,9 @@
}
},
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@ -3782,9 +3771,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@ -5031,12 +5020,12 @@
}
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"dependencies": {
"braces": "^3.0.2",
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@ -6985,9 +6974,9 @@
"dev": true
},
"node_modules/sweetalert2": {
"version": "11.10.6",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.6.tgz",
"integrity": "sha512-CINZPLZXZRSZqSOE7H7j1F7X8e8O1kLOiXPmtJn1DYxvXsKBr3d16d90+IcwTTs7dJww20h8r8QIxIwsLGX+6A==",
"version": "11.14.0",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.14.0.tgz",
"integrity": "sha512-kF1Q/+GtZZXr+rYVcBNwlEsnxP089CpDbck+MYjvLaQj9x4fzHqN9UhlkHOIR0k09LVu2sx8cU9BnvRlxWIZqg==",
"dev": true,
"funding": {
"type": "individual",
@ -7553,9 +7542,9 @@
}
},
"node_modules/vite": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
"integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
"integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
"dev": true,
"dependencies": {
"esbuild": "^0.18.10",
@ -8273,9 +8262,9 @@
"dev": true
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
"dev": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
@ -8286,27 +8275,26 @@
}
},
"node_modules/webpack": {
"version": "5.90.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.0.tgz",
"integrity": "sha512-bdmyXRCXeeNIePv6R6tGPyy20aUobw4Zy8r0LUS2EWO+U+Ke/gYDgsCh7bl5rB6jPpr4r0SZa6dPxBxLooDT3w==",
"version": "5.94.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
"@webassemblyjs/ast": "^1.11.5",
"@webassemblyjs/wasm-edit": "^1.11.5",
"@webassemblyjs/wasm-parser": "^1.11.5",
"@webassemblyjs/ast": "^1.12.1",
"@webassemblyjs/wasm-edit": "^1.12.1",
"@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.9.0",
"acorn-import-attributes": "^1.9.5",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.15.0",
"enhanced-resolve": "^5.17.1",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.9",
"graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
@ -8314,7 +8302,7 @@
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.10",
"watchpack": "^2.4.0",
"watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
"bin": {

View file

@ -20,7 +20,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.5",
"@ldc-web/cookie-notice": "^4.1.0",
"@ldc-web/cookie-notice": "^6.0.3",
"@sipec/vue3-tags-input": "^3.0.4",
"@types/bootstrap": "^5.2.7",
"@types/node": "^20.8.2",

View file

@ -225,7 +225,6 @@ return [
'female' => 'of the ',
'vowel' => 'of the '
],
'accept_rules' => 'acceptation of rules',
'activated' => 'activated',
'attribute_alt' => 'alt attribute',
'attribute_title' => 'title attribute',
@ -272,7 +271,6 @@ return [
'product_name' => 'product name',
'publication' => 'publication',
'publish_at' => 'publication date',
'send_data' => 'autorization to send data',
'seo_description' => 'SEO description',
'seo_title' => 'SEO title',
'seo' => 'SEO',

View file

@ -1,28 +1,22 @@
<?php
// * Version 4.0.0
// phpcs:disable
return [
'button_customize_cookies' => 'Personnaliser les cookies',
'button_close_cookies' => 'Fermer la fenêtre des cookies',
'button_forbid' => 'Interdire',
'button_allow' => 'Autoriser',
'button_toggle_cookie' => 'Autoriser ou refuser',
'button_forbid_all' => 'Tout refuser',
'button_allow_all' => 'Tout accepter',
'button_forbid_all_title' => 'Refuser tous les cookies et fermer le panneau des cookies',
'button_allow_all_title' => 'Accepter tous les cookies et fermer le panneau des cookies',
'button_customize' => 'Personnaliser',
'button_back' => 'Retour',
'button_validate_and_close' => 'Valider et fermer',
'button_title_open_new_tab' => 'Ouvrir le lien dans un nouvel onglet',
'banner_title' => 'Le site internet :site_name utilise des cookies !',
'banner_text' => 'Nous utilisons des cookies pour nous assurer du bon fonctionnement de notre site et à des fins analytiques.
Vous pouvez changer d’avis à tout moment en cliquant sur l’icône présente sur chaque page de notre site.
En autorisant ces services tiers, vous acceptez le dépôt et la lecture de cookies et l’utilisation de technologies de suivi nécessaires à leur bon fonctionnement.',
'modal_title' => 'Fenêtre de gestion de cookies',
'panel_title' => 'Panneau de gestion des cookies',
'panel_content' => 'Contenu du panneau des cookies',
'panel_subtitle' => 'Le respect de votre vie privée est notre priorité',
'panel_details' => 'Les fonctionnalités de ce site s’appuient sur des services proposés par des tiers. Si vous acceptez, ces tiers déposeront des cookies qui vous permettront de visualiser sur le site du contenu hébergé par ces tiers. Via ces cookies, ces tiers collecteront et utiliseront vos données de navigation pour des finalités qui leur sont propres, conformément à leur politique de confidentialité (lien ci-dessous). Cette page vous permet de donner ou de retirer votre consentement, soit globalement soit service par service.',
'picture_cookie_title' => 'Image d’un bon gros cookie',
'navigation_title' => 'Navigation du panneau des cookies',
'custom' => [
@ -36,22 +30,16 @@ return [
'labelLink' => 'En apprendre plus',
'warning' => 'Vous devez accepter les cookies pour visionner cette vidéo',
],
'vimeo' => [
'name' => 'Vimeo',
'description' => 'Les cookies placés via les services de partage de vidéos sont destinés à permettre à l’utilisateur de visionner des contenus multimédias directement sur le site.',
'labelLink' => 'En apprendre plus',
'warning' => 'Vous devez accepter les cookies pour visionner cette vidéo',
],
'matomo' => [
'title' => 'Matomo',
'description' => 'Les services de mesure d’audience permettent de générer des statistiques de fréquentation utiles à l’amélioration du site.',
'labelLink' => 'En apprendre plus',
],
'recaptcha' => [
'title' => 'reCAPTACHA',
'title' => 'reCAPTCHA',
'description' => 'Les cookies qui sont déposés via le recaptcha sur les formulaires ont pour finalité d’empêcher que ceux-ci ne soient soumis par des robots.',
'labelLink' => 'En apprendre plus',
'warning' => 'Vous devez accepter les cookies reCAPTACHA pour envoyer le formulaire',
'warning' => 'Vous devez accepter les cookies reCAPTCHA pour envoyer le formulaire',
]
]
];

View file

@ -227,7 +227,6 @@ return [
'female' => 'de la ',
'vowel' => 'de l\''
],
'accept_rules' => 'acceptation des règles',
'activated' => 'activé',
'attribute_alt' => 'attribut alt',
'attribute_title' => 'attribut title',
@ -274,7 +273,6 @@ return [
'product_name' => 'nom du produit',
'publication' => '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',

View file

@ -20,8 +20,21 @@
<p class="text-capitalize m-0 text-center">{{ __('T. +33 (0)4 90 80 99 99') }}</p>
</div>
</div>
<div class="border-3 border-dark fw-bold rounded-4 cn-cookie-activate d-flex flex-column flex-md-row align-items-center mb-3 mt-4 border bg-white p-3"
data-cookie-name="recaptcha">
<span class="d-flex flex-column w-md-75 w-100">
<strong class="text-underline text-bold text-dark fs-6 mb-2">
{{ __('cookie-notice.custom.recaptcha.warning') }}
</strong>
<small class="text-dark fw-normal fs-6">
{{ __('Acceptez ce cookie pour utiliser les formulaires') }}
</small>
</span>
<button class="btn btn-secondary w-lg-25 h-50 fs-6 rounded-4 mt-md-0 mt-3 border-0"
id="recaptcha-accept">{{ __('AUTORISER') }}</button>
</div>
</div>
<form id="contact-form" method="POST" action="{{ route('fo.contact.store') }}" enctype="multipart/form-data">
<form id="contact-form" method="POST" action="{{ route('fo.contact.store') }}" enctype="multipart/form-data" inert>
@method('POST')
@csrf
<div class="bg-agis-yellow mb-md-5 m-0 pb-5">
@ -33,7 +46,7 @@
<div class="row w-100 mx-auto">
<div class="col-12 col-md-6 p-0">
<div class="h-100 me-md-5 position-relative">
<fieldset class="select-form d-flex flex-column justify-content-end align-items-start h-100" inert="true">
<fieldset class="select-form d-flex flex-column justify-content-end align-items-start h-100">
<select class="form-control text-capitalize" name="civility" role="button">
<option class="text-capitalize" disabled selected>{{ __('validation.custom.civility') }}</option>
@foreach (\App\Enums\Contact\CivilityEnum::toArray() as $key => $enumObject)
@ -47,56 +60,56 @@
</div>
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.last_name'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="last_name" value="{{ old('last_name') }}">
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.first_name'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="first_name" value="{{ old('first_name') }}">
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1">{{ Str::of(__('validation.custom.society'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="society" value="{{ old('society') }}">
</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" inert="true">
<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>
<input class="form-control" name="email" value="{{ old('email') }}" required>
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1">{{ Str::of(__('validation.attributes.phone'))->ucFirst() }}&nbsp;:</label>
<input class="form-control" name="phone" type="number" value="{{ old('phone') }}">
</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" inert="true">
<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>
</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" inert="true">
<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>
</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" inert="true">
<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>
</fieldset>
</div>
<div class="col-12 col-md-6 p-0">
<div class="ms-md-5 position-relative pt-md-0 h-100 pt-4">
<fieldset class="select-form d-flex flex-column justify-content-end align-items-start h-100" inert="true">
<fieldset class="select-form d-flex flex-column justify-content-end align-items-start h-100">
<select class="form-control text-capitalize" name="object" role="button" required>
<option class="text-capitalize" disabled selected>{{ __('validation.custom.object') }}</option>
@foreach (\App\Enums\Contact\ObjectEnum::toArray() as $key => $enumObject)
@ -114,7 +127,7 @@
{{ Str::of(__('pour pouvoir vous répondre nous avons besoin de quelques informations :'))->ucFirst()->value() }}
</p>
<div class="col-12 col-md-6 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1" for="product_name">
{{ Str::of(__('validation.custom.product_name'))->ucFirst()->value() }}*&nbsp;:
</label>
@ -123,7 +136,7 @@
</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" inert="true">
<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>
@ -133,7 +146,7 @@
</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" inert="true">
<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;:
@ -143,7 +156,7 @@
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1" for="product_lot">
{{ Str::of(__('validation.custom.product_lot'))->ucFirst()->value() }}*&nbsp;:
</label>
@ -152,7 +165,7 @@
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start pe-md-5">
<label class="mt-1" for="product_date_consumption">
{{ Str::of(__('validation.custom.product_date_consumption'))->ucFirst()->value() }}*&nbsp;:
<span class="text-body-secondary">{{ __('Ex : 25/08/2028') }}</span>
@ -162,7 +175,7 @@
</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" inert="true">
<fieldset class="d-flex flex-column justify-content-center align-items-start ps-md-5">
<label class="mt-1" for="product_location">
{{ Str::of(__('validation.custom.product_location'))->ucFirst()->value() }}*&nbsp;:
</label>
@ -171,7 +184,7 @@
</fieldset>
</div>
<div class="col-12 my-3 p-0">
<fieldset class="row" inert="true">
<fieldset class="row">
<div class="col-12 col-md-6 pe-md-5 m-xl-0 mb-2">
<p class="mb-0 mt-1">
{{ Str::of(__('souhaitez-vous joindre une photo ?'))->ucFirst()->value() }}
@ -195,61 +208,24 @@
</p>
</div>
<div class="col-12 mb-3 p-0">
<fieldset class="d-flex flex-column justify-content-center align-items-start" inert="true">
<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;:
</label>
<textarea class="form-control" id="message" name="message" rows="6" required>{{ old('message') }}</textarea>
</fieldset>
</div>
<div class="col-12 mb-1 p-0">
<fieldset class="d-flex justify-content-start align-items-start align-items-md-center flex-row"
inert="true">
<input class="form-check-input rounded-0 mt-2 p-3" id="accept_rules" name="accept_rules" type="checkbox"
value="{{ old('accept_rules') }}" role="button" required>
<label class="ms-2 mt-1" for="accept_rules" role="button">
{!! nl2br(
__('contact.acceptcgu', [
'startA' => '<a href="' . route('fo.policies.show') . '">',
'endA' => '</a>',
]),
) !!}
</label>
</fieldset>
</div>
<div class="col-12 mb-1 p-0">
<fieldset class="d-flex justify-content-start align-items-start align-items-md-center flex-row"
inert="true">
<input class="form-check-input rounded-0 mt-2 p-3" id="send_data" name="send_data" type="checkbox"
value="{{ old('send_data') }}" role="button" required>
<label class="ms-2 mt-1" for="send_data" role="button">
{!! nl2br(
__('contact.senddata', [
'startA' => '<a href="' . route('fo.legals.show') . '">',
'endA' => '</a>',
]),
) !!}
</label>
</fieldset>
</div>
<div class="col text-center">
<span>{!! clean(
__(
'Les informations recueillies à partir de ce formulaire sont traitées par le Responsable de Traitement pour donner suite à votre demande de contact. Pour connaître vos droits, vous pouvez consulter la :startA Charte de confidentialité:endA. !',
[
'startA' => '<a href="' . route('fo.legals.show') . '">',
'startA' => '<a href="' . route('fo.policies.show') . '">',
'endA' => '</a>',
],
),
) !!}</span>
</div>
<span id="recaptcha-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.recaptcha.warning') }}
</strong>
<button class="btn btn-sm btn-primary"
id="recaptcha-accept">{{ __('Accepter Recaptcha uniquement') }}</button>
</span>
<div class="d-flex flex-column justify-content-center align-items-center">
<div id="r_captcha"></div>
@if ($errors->has('g-recaptcha-response'))
@ -262,8 +238,8 @@
</div>
</div>
<button class="g-recaptcha btn btn-primary w-100 text-capitalize"
data-sitekey="{{ config('services.google.recaptcha.public') }}" type="submit"
inert="true">{{ Str::ucfirst(__('contact.send')) }}</button>
data-sitekey="{{ config('services.google.recaptcha.public') }}"
type="submit">{{ Str::ucfirst(__('contact.send')) }}</button>
</div>
</form>
</section>
@ -272,7 +248,14 @@
@push('scripts')
<script nonce="{{ $nonce }}">
document.addEventListener('DOMContentLoaded', function() {
const initFormCaptcha = () => {
const newDiv = document.createElement("div");
newDiv.classList.add('g-recaptcha');
document.getElementById('r_captcha').appendChild(newDiv);
document.getElementById('contact-form').inert = true;
};
window.__CN_Recaptcha = function() {
initFormCaptcha();
(function(d, t) {
let g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
@ -280,16 +263,16 @@
s.parentNode.insertBefore(g, s)
}(document, 'script'));
};
window.__CN_Recaptcha_Reset = function() {
document.querySelector('#r_captcha > div')?.remove();
};
window.__CN_Recaptcha_Loaded = function() {
grecaptcha.render('r_captcha', {
document.getElementById('contact-form').inert = false;
grecaptcha.render(document.querySelector('#r_captcha > div'), {
'sitekey': '{{ config('services.google.recaptcha.public') }}'
});
document.getElementById('recaptcha-warning').remove();
document.getElementById('contact-form').querySelectorAll('[inert="true"]').forEach(element => {
element.inert = false;
});
};
document.getElementById("recaptcha-accept")?.addEventListener('click', function(e) {
document.getElementById("recaptcha-accept").addEventListener('click', function(e) {
e.preventDefault();
window.WebCookieNotice.acceptCookie('recaptcha');
});

View file

@ -22,26 +22,12 @@
@if ($homepageModel->display_video)
<div class="ratio ratio-16x9 y-video">
@if (\App\Rules\IsValidVimeoId::validates($homepageModel->video_id))
<div class="video-inlaid" type="vimeo"
href="https://player.vimeo.com/video/{{ $homepageModel->video_id }}?autoplay=1&loop=1&badge=0">
<a class="cn-cookie-link" id="vimeo-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.vimeo.warning') }}
</strong>
</a>
</div>
<div class="cn-vimeo" data-id="{{ $homepageModel->video_id }}"></div>
@endif
@if (\App\Rules\IsValidYoutubeId::validates($homepageModel->video_id))
{{-- For loop to work need to provide a playlist --}}
{{-- http://web.archive.org/web/20121016180134/http://brianwong.com/blog/2012-youtube-embed-code-autoplay-on-and-all-other-parameters/ --}}
<div class="video-inlaid" type="youtube"
href="https://www.youtube.com/embed/{{ $homepageModel->video_id }}?autoplay=1&loop=1">
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.youtube.warning') }}
</strong>
</a>
</div>
<div class="cn-youtube" data-id="{{ $homepageModel->video_id }}"></div>
@endif
</div>
@else
@ -170,8 +156,7 @@
</p>
</div>
<img src="{{ asset($rangeModel->picture_thumbnail) }}"
title="{{ $rangeModel->picture_thumbnail_title }}"
alt="{{ $rangeModel->picture_thumbnail_alt }}">
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>

View file

@ -104,22 +104,10 @@
<p>{{ __('Une équipe de talents à renforcer.') }}</p>
<div class="ratio ratio-16x9">
@if (\App\Rules\IsValidYoutubeId::validates($joinuspageModel->video_id))
<div class="video-inlaid" type="youtube" href="https://www.youtube.com/embed/{{ $joinuspageModel->video_id }}">
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.youtube.warning') }}
</strong>
</a>
</div>
<div class="cn-youtube" data-id="{{ $joinuspageModel->video_id }}"></div>
@endif
@if (\App\Rules\IsValidVimeoId::validates($joinuspageModel->video_id))
<div class="video-inlaid" type="vimeo" href="https://player.vimeo.com/video/{{ $joinuspageModel->video_id }}">
<a class="cn-cookie-link" id="vimeo-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.vimeo.warning') }}
</strong>
</a>
</div>
<div class="cn-vimeo" data-id="{{ $joinuspageModel->video_id }}"></div>
@endif
</div>
<p>

View file

@ -11,24 +11,87 @@ $strings = (object)[
'button_customize_cookies' => __('cookie-notice.button_customize_cookies'),
'button_close_cookies' => __('cookie-notice.button_close_cookies'),
'button_title_open_new_tab' => __('cookie-notice.button_title_open_new_tab'),
'button_forbid' => __('cookie-notice.button_forbid'),
'button_allow' => __('cookie-notice.button_allow'),
'button_toggle_cookie' => __('cookie-notice.button_toggle_cookie'),
'button_forbid_all' => Str::upper(__('cookie-notice.button_forbid_all')),
'button_allow_all' => Str::upper(__('cookie-notice.button_allow_all')),
'button_customize' => Str::upper(__('cookie-notice.button_customize')),
'button_forbid_all_title' => __('cookie-notice.button_forbid_all_title'),
'button_allow_all_title' => __('cookie-notice.button_allow_all_title'),
'button_back' => Str::upper(__('cookie-notice.button_back')),
'button_validate_and_close' => Str::upper(__('cookie-notice.button_validate_and_close')),
'banner_title' => __('cookie-notice.banner_title', ['site_name' => $site_name]),
'banner_text' => __('cookie-notice.banner_text'),
'panel_title' => __('cookie-notice.panel_title'),
'banner_text' => sprintf(
"%s<br><br>%s",
"Nous utilisons des cookies pour nous assurer du bon fonctionnement de notre site et à des fins analytiques. Vous pouvez changer d'avis à tout moment en cliquant sur l'icône présente sur chaque page de notre site. En autorisant ces services tiers, vous acceptez le dépôt et la lecture de cookies et l'utilisation de technologies de suivi nécessaires à leur bon fonctionnement.",
"<a href='/charte-de-confidentialite'>Charte de confidentialité</a>"
),
'panel_content' => __('cookie-notice.panel_content'),
'panel_subtitle' => __('cookie-notice.panel_subtitle'),
'panel_details' => __('cookie-notice.panel_details'),
'picture_cookie_title' => __('cookie-notice.picture_cookie_title'),
'navigation_title' => __('cookie-notice.navigation_title'),
];
$cookieInline = function ($cookieName, $text, $subtext = '') {
return <<<SCRIPT
(() => {
const cookieActivateContainer = document.createElement("div");
cookieActivateContainer.classList.add(
'd-flex',
'justify-content-center',
'align-items-center'
);
const cookieActivate = document.createElement("span");
cookieActivate.classList.add(
'cn-cookie-activate',
'border',
'border-3',
'border-dark',
'p-3',
'rounded-3',
'text-center'
);
cookieActivate.dataset.cookieName = '{$cookieName}';
const childSpan = document.createElement("span");
const childSpanSpan = document.createElement("span");
childSpanSpan.classList.add(
'text-dark',
'fs-6',
'fw-bold',
'lh-sm'
);
const childSpanSmall = document.createElement("span");
childSpanSmall.classList.add(
'small-text',
'fs-6',
'lh-sm'
);
childSpanSpan.textContent = '{$text}';
childSpanSmall.textContent = '{$subtext}';
childSpan.appendChild(childSpanSpan);
childSpan.appendChild(childSpanSmall);
const childBtn = document.createElement("button");
childBtn.classList.add(
'btn',
'btn-secondary',
'rounded-2',
'border-0',
'fs-6',
'fw-bold',
'ms-3',
'px-4',
'py-3'
);
childBtn.textContent = 'Autoriser';
cookieActivate.appendChild(childSpan);
cookieActivate.appendChild(childBtn);
cookieActivateContainer.appendChild(cookieActivate);
return cookieActivateContainer;
})
SCRIPT;
};
$cookies = [];
// YOUTUBE
@ -37,52 +100,42 @@ $cookies['youtube'] = [
'description' => __('cookie-notice.custom.youtube.description'),
'labelLink' => __('cookie-notice.custom.youtube.labelLink'),
'link' => 'https://policies.google.com/technologies/cookies?hl=fr&utm_source=ucb',
'labelLink' => __('En savoir +'),
'cookies' => ['NID', 'VISITOR_INFO1_LIVE', 'YSC']
'cookies' => [
"NID", "ENID", "_Secure-ENID", "VISITOR_INFO1_LIVE", "YEC", "__Secure-YEC", "YSC",
"GEUP", "PREF", "pm_sess", "CGIC", "SOCS", "GPS", "yt-player-bandwidth", "yt-player-headers-readable"
]
];
$inlineYt = $cookieInline(
'youtube',
'Youtube est désactivé'
);
$cookies['youtube']['script'] = <<<SCRIPT
function () {
// * Video inlaid.
const videoInlaidList = document.querySelectorAll('.video-inlaid[type="youtube"]');
for (const videoLink of videoInlaidList) {
if (!videoLink.getAttribute("type")) {
throw new Error("Missing attribute type");
}
if (!videoLink.getAttribute("href")) {
throw new Error("Missing attribute href");
}
videoLink.innerHTML = "";
const newIframe = document.createElement("iframe");
newIframe.frameBorder = "0";
newIframe.allow = "fullscreen";
newIframe.width = "1920px";
newIframe.height = "1080px";
newIframe.classList.add("w-100");
newIframe.classList.add("h-100");
newIframe.setAttribute("allowfullscreen", "allowfullscreen");
newIframe.src = String(videoLink.getAttribute("href"));
videoLink.appendChild(newIframe);
let youtubeVids = document.getElementsByClassName('cn-youtube');
for (let item of youtubeVids) {
let id = item.dataset.id;
let e = document.createElement('iframe');
e.src = "https://www.youtube.com/embed/" + id + "?autoplay=1&loop=1&playlist=" + id;
e.width = "1920px";
e.height = "1080px";
e.classList.add("w-100");
e.classList.add("h-100");
e.frameBorder = "0";
e.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
e.allowFullscreen = true;
item.innerHTML = "";
item.appendChild(e);
}
}
SCRIPT;
$cookies['youtube']['fallback'] = <<<FALLBACK
function () {
// * Video inlaid.
const videoInlaidList = document.querySelectorAll('.video-inlaid[type="youtube"]');
for (const item of videoInlaidList) {
let a = document.createElement('a');
a.innerText = 'Autoriser';
a.classList.add('cn-cookie-link');
a.setAttribute('role', 'button');
a.onclick = function () {
WebCookieNotice.openCookieModalToCookiePage();
};
let e = document.createElement('p');
e.innerHTML = 'Youtube est désactivé. ';
let youtubeVids = document.getElementsByClassName('cn-youtube');
for (let item of youtubeVids) {
item.innerHTML = "";
e.appendChild(a);
item.appendChild(e);
item.appendChild({$inlineYt}());
setTimeout(() => listenInlineCnButtons(), 500);
}
}
FALLBACK;
@ -93,61 +146,55 @@ $cookies['vimeo'] = [
'description' => __('Les cookies déposés via les services de partage de vidéo ont pour finalité de permettre à l’utilisateur de visionner directement sur le site le contenu multimédia.'),
'link' => 'https://vimeo.com/cookie_policy',
'labelLink' => __('En savoir +'),
'cookies' => ['NID', 'VISITOR_INFO1_LIVE', 'YSC']
'cookies' => [
"vuid", "__utmt_player"
]
];
$inlineVo = $cookieInline(
'vimeo',
'Vimeo est désactivé'
);
$cookies['vimeo']['script'] = <<<SCRIPT
function () {
let videoInlaidList = document.querySelectorAll('.video-inlaid[type="vimeo"]');
for (const videoLink of videoInlaidList) {
if (!videoLink.getAttribute("type")) {
throw new Error("Missing attribute type");
}
if (!videoLink.getAttribute("href")) {
throw new Error("Missing attribute href");
}
videoLink.innerHTML = "";
const newIframe = document.createElement("iframe");
newIframe.frameBorder = "0";
newIframe.allow = "fullscreen";
newIframe.width = "1920px";
newIframe.height = "1080px";
newIframe.classList.add("w-100");
newIframe.classList.add("h-100");
newIframe.setAttribute("allowfullscreen", "allowfullscreen");
newIframe.src = String(videoLink.getAttribute("href"));
videoLink.appendChild(newIframe);
let vimeoVids = document.getElementsByClassName('cn-vimeo');
for (let item of vimeoVids) {
let id = item.dataset.id;
let e = document.createElement('iframe');
e.src = "https://player.vimeo.com/video/" + id + "?autoplay=1&loop=1&badge=0";
e.width = "1920px";
e.height = "1080px";
e.classList.add("w-100");
e.classList.add("h-100");
e.frameBorder = "0";
e.allow = "autoplay; fullscreen; picture-in-picture";
e.allowFullscreen = true;
item.innerHTML = "";
item.appendChild(e);
}
}
SCRIPT;
$cookies['vimeo']['fallback'] = <<<FALLBACK
function () {
let videoInlaidList = document.querySelectorAll('.video-inlaid[type="vimeo"]');
for (const item of videoInlaidList) {
let a = document.createElement('a');
a.innerText = 'Autoriser';
a.classList.add('cn-cookie-link');
a.setAttribute('role', 'button');
a.onclick = function () {
WebCookieNotice.openCookieModalToCookiePage();
};
let e = document.createElement('p');
e.innerHTML = 'Vimeo est désactivé. ';
let vimeoVids = document.getElementsByClassName('cn-vimeo');
for (let item of vimeoVids) {
item.innerHTML = "";
e.appendChild(a);
item.appendChild(e);
item.appendChild({$inlineVo}());
setTimeout(() => listenInlineCnButtons(), 500);
}
}
FALLBACK;
// RECAPTCHA
$cookies['recaptcha'] = [
'name' => __('cookie-notice.custom.recaptcha.title'),
'description' => __('cookie-notice.custom.recaptcha.description'),
'link' => 'https://policies.google.com/privacy',
'labelLink' => __('En savoir +'),
'cookies' => ['NID', '__Secure-3PAPISID', '__Secure-3PSID', '__Secure-3PSIDCC']
'name' => __('cookie-notice.custom.recaptcha.title'),
'description' => __('cookie-notice.custom.recaptcha.description'),
'link' => 'https://policies.google.com/privacy',
'labelLink' => __('cookie-notice.custom.recaptcha.labelLink'),
'cookies' => [
"NID", "_grecaptcha", "__Secure-3PAPISID", "__Secure-3PSID", "__Secure-3PSIDCC",
"_GRECAPTCHA", "rc::c", "rc::b", "rc::a", "itsec-recaptcha-opt-in-*"
]
];
$cookies['recaptcha']['script'] = <<<SCRIPT
@ -155,16 +202,39 @@ function () {
if (window.__CN_Recaptcha) {
window.__CN_Recaptcha();
}
[...document.getElementsByClassName('cn-cookie-activate')].forEach(function(el) {
if (el.dataset.cookieName === 'recaptcha') {
el.classList.add('d-none');
document.getElementById('contact-form').inert = false;
}
});
}
SCRIPT;
$cookies['recaptcha']['fallback'] = <<<FALLBACK
function () {
if (window.__CN_Recaptcha_Reset) {
window.__CN_Recaptcha_Reset();
}
[...document.getElementsByClassName('cn-cookie-activate')].forEach(function(el) {
if (el.dataset.cookieName === 'recaptcha') {
el.classList.remove('d-none');
document.getElementById('contact-form').inert = true;
}
});
}
FALLBACK;
// MATOMO
$cookies['matomo'] = [
'name' => __('cookie-notice.custom.matomo.title'),
'description' => __('cookie-notice.custom.matomo.description'),
'link' => 'https://fr.matomo.org/gdpr-analytics/',
'labelLink' => __('En savoir +'),
'cookies' => ['_pk']
'labelLink' => __('cookie-notice.custom.matomo.labelLink'),
'cookies' => [
"_pk*",
"_pk_ref", "_pk_cvar", "_pk_id", "_pk_ses", "_pk_hsr", "piwik_ignore", "_pk_uid",
"_pk_ref", "_pk_cvar", "_pk_id", "_pk_ses", "_pk_hsr", "mtm_consent", "matomo_ignore", "matomo_sessid"
]
];
$cookies['matomo']['script'] = <<<SCRIPT
@ -216,6 +286,24 @@ document.addEventListener('DOMContentLoaded', function () {
window.WebCookieNotice['{{ $index_name }}'] = window.WebCookieNotice['{{ $index_name }}'].conf;
@endforeach
window.WebCookieNotice = new window.CookieNotice(window.WebCookieNotice);
function listenInlineCnButtons() {
const cookieInlineActivation =
document.getElementsByClassName("cn-cookie-activate");
[...cookieInlineActivation].forEach((cookieEl) => {
const cookieBtnActivation = cookieEl.querySelector("button");
if (!cookieBtnActivation) {
throw new Error("Invalid template cookie button");
}
cookieBtnActivation.addEventListener("click", (e) => {
e.preventDefault();
if (cookieEl.dataset.cookieName) {
window.WebCookieNotice.acceptCookie(cookieEl.dataset.cookieName);
cookieEl.classList.add("d-none");
}
});
});
};
});
</script>
@endpush

View file

@ -33,19 +33,14 @@
<span>{!! nl2br(e($strings->banner_title)) !!}</span>
</div>
<div class="cn-banner-para-p">
<p>{!! nl2br(e($strings->banner_text)) !!}</p>
<p>{!! clean($strings->banner_text) !!}</p>
</div>
</div>
</div>
{{-- 2ND PAGE CUSTOMIZE PANEL --}}
<div class="cn-modal-container d-none">
<p class="cn-modal-title" aria-level="h2">{{ $strings->panel_title }}</p>
<p class="cn-modal-subtitle">{!! nl2br(e($strings->panel_subtitle)) !!}</p>
<p class="cn-modal-description">{!! nl2br(e($strings->panel_details)) !!}</p>
<div class="cn-modal-wrapper">
{{-- COOKIES LIST --}}
<ul id="cn-modal-list"></ul>
</div>
{{-- COOKIES LIST --}}
<ul id="cn-modal-list"></ul>
</div>
</div>
{{-- NAV BAR --}}
@ -54,7 +49,7 @@
title="{{ $strings->button_forbid_all_title }}">{{ $strings->button_forbid_all }}</button>
<button class="cn-banner-btn cn-accept" id="cn-accept-banner"
title="{{ $strings->button_allow_all_title }}">{{ $strings->button_allow_all }}</button>
<button class="cn-banner-btn cn-custom" id="cn-settings-banner" data-open-modal="{{ $strings->button_back }}"
<button class="cn-banner-btn cn-custom" id="cn-settings-banner" data-open-modal="{{ $strings->button_validate_and_close }}"
data-close-modal="{{ $strings->button_customize }}">{{ $strings->button_customize }}</button>
</div>
@ -67,14 +62,11 @@
<a class="cn-cookie-link" title="{{ $strings->button_title_open_new_tab }}" target="blank">#link</a>
</div>
<div class="cn-cookie-buttons">
<div class="deny">
<input id="" name="" data-name="" data-status="false" type="radio">
<label for="" role="button" tabindex="0">{{ $strings->button_forbid }}</label>
</div>
<div class="accept">
<input id="" name="" data-name="" data-status="true" type="radio">
<label for="" role="button" tabindex="0">{{ $strings->button_allow }}</label>
</div>
<label class="cn-switch" title="{{ $strings->button_toggle_cookie }}" role="checkbox"
aria-label="{{ $strings->button_toggle_cookie }}" aria-checked="undefined" tabindex="0">
<input type="checkbox" tabindex="-1" />
<span></span>
</label>
</div>
</div>
</div>