Init compilation, linters, cookies

This commit is contained in:
S. Hattry 2022-09-08 11:36:15 +02:00
parent 124344518e
commit 5ab4df3663
42 changed files with 5560 additions and 994 deletions

41
.eslintrc.json Normal file
View file

@ -0,0 +1,41 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-strongly-recommended",
"@vue/eslint-config-typescript"
],
"overrides": [
{
"files": ["*.ts", "*.vue"],
"rules": {
"no-undef": "off"
}
},
{
"files": ["*.vue"],
"rules": {
"indent": "off"
}
}
],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser",
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["vue", "@typescript-eslint"],
"ignorePatterns": ["webpack.mix.js", "**/vendor/*.js", "**/vendor/**/*.js"],
"rules": {
"indent": ["error", 4, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"vue/script-indent": ["error", 2, { "baseIndent": 0 }],
"vue/one-component-per-file": "off"
}
}

View file

@ -1,11 +1,10 @@
image: $CI_REGISTRY/service-web-lab/ldc-web-images-docker/ldcweb-qa:php7.3-1.0
stages:
- Security
- CodingStandards
- Builds
composer-security:
stage: Security
image: $CI_REGISTRY/service-web-lab/ldc-web-images-docker/ldcweb-qa:php7.3-1.0
script:
- local-php-security-checker --format=json --path=./composer.lock > composer-security-checker-report.json
artifacts:
@ -14,9 +13,12 @@ composer-security:
paths:
- composer-security-checker-report.json
allow_failure: true
needs: []
npm-security:
stage: Security
image: node:17.9.0
before_script:
- npm install --location=global audit-ci@^6
script:
- audit-ci -p npm -o json > npm-security-checker-report.json
artifacts:
@ -25,9 +27,10 @@ npm-security:
paths:
- npm-security-checker-report.json
allow_failure: true
needs: []
phpcs:
stage: CodingStandards
image: $CI_REGISTRY/service-web-lab/ldc-web-images-docker/ldcweb-qa:php7.3-1.0
before_script:
- composer config gitlab-token.gitlab.com $CI_DEPLOY_USER $CI_DEPLOY_PASSWORD
- composer install
@ -43,4 +46,67 @@ phpcs:
- phpcs-report.xml
reports:
junit: phpcs-report.xml
allow_failure: false
allow_failure: false
needs:
- composer-security
- npm-security
eslint:
stage: CodingStandards
image: node:17.9.1
before_script:
- npm install
cache:
paths:
- node_modules/
script:
- npm run eslint-ci --silent > eslint-report.xml
artifacts:
when: on_failure
expose_as: 'eslint'
paths:
- eslint-report.xml
reports:
junit: eslint-report.xml
allow_failure: false
needs:
- composer-security
- npm-security
stylelint:
stage: CodingStandards
image: node:17.9.1
before_script:
- npm install
cache:
paths:
- node_modules/
script:
- npm run stylelint-ci --silent > stylelint-report.json
artifacts:
when: on_failure
expose_as: 'stylelint'
paths:
- stylelint-report.json
allow_failure: false
needs:
- composer-security
- npm-security
front-build:
stage: Builds
image: node:17.9.1
before_script:
- npm install
cache:
paths:
- node_modules/
script:
- npm run prod > front-build-report.json
artifacts:
when: on_failure
expose_as: 'front-build-report'
paths:
- front-build-report.json
allow_failure: false
needs:
- phpcs
- eslint
- stylelint

27
.stylelintrc.json Normal file
View file

@ -0,0 +1,27 @@
{
"extends": [
"stylelint-config-sass-guidelines",
"stylelint-config-idiomatic-order"
],
"ignoreFiles": [
"**/vendor/*.css",
"**/vendor/**/*.css",
"**/vendor/*.scss",
"**/vendor/**/*.scss",
"**/vendor/*.sass",
"**/vendor/**/*.sass",
"**/vendor/*.less",
"**/vendor/**/*.less"
],
"customSyntax": "postcss-scss",
"rules": {
"indentation": 4,
"string-quotes": "double",
"selector-max-id": null,
"color-no-invalid-hex": true,
"selector-no-qualifying-type": null,
"order/properties-alphabetical-order": null,
"max-nesting-depth": 10,
"selector-max-compound-selectors": 10
}
}

22
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
"peacock.remoteColor": "#161719",
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#2e3034",
"activityBar.background": "#2e3034",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#a7385d",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#e7e7e799",
"sash.hoverBorder": "#2e3034",
"statusBar.background": "#161719",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#2e3034",
"statusBarItem.remoteBackground": "#161719",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#161719",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#16171999",
"titleBar.inactiveForeground": "#e7e7e799"
}
}

View file

@ -0,0 +1,16 @@
<?php
namespace App\Http\Controllers;
class HomeController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
return view('fo.pages.home');
}
}

View file

@ -3,6 +3,7 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\URL;
class AppServiceProvider extends ServiceProvider
{
@ -22,5 +23,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
URL::forceScheme('https');
}
}

5
config/google.php Normal file
View file

@ -0,0 +1,5 @@
<?php
return [
'analyticsKey' => env('ANALYTICS_GOOGLE_ID')
];

3
jsconfig.json Normal file
View file

@ -0,0 +1,3 @@
{
"include": ["./resources/js/**/*"]
}

3635
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,19 +7,42 @@
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
"production": "mix --production",
"eslint": "node ./node_modules/.bin/eslint -c .eslintrc.json ./resources",
"eslint-ci": "node ./node_modules/.bin/eslint -c .eslintrc.json ./resources -f junit",
"stylelint": "npx stylelint '**/*.scss'",
"stylelint-ci": "npx stylelint '**/*.scss' -f json"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.4",
"@types/bootstrap": "^5.2.3",
"@types/webpack-env": "^1.18.0",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"@vue/eslint-config-typescript": "^11.0.0",
"axios": "^0.21",
"bootstrap": "^5.2.0",
"clean-webpack-plugin": "^4.0.0",
"eslint": "^8.23.0",
"eslint-plugin-vue": "^9.4.0",
"eslint-webpack-plugin": "^3.2.0",
"laravel-mix": "^6.0.6",
"laravel-mix-clean": "^0.1.0",
"laravel-mix-eslint": "^0.2.0",
"laravel-mix-polyfill": "^3.0.1",
"laravel-mix-stylelint": "^1.0.0",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"prettier": "^2.7.1",
"resolve-url-loader": "^5.0.0",
"sass": "^1.54.8",
"sass-loader": "^12.6.0",
"stylelint": "^14.11.0",
"stylelint-config-idiomatic-order": "^8.1.0",
"stylelint-config-sass-guidelines": "^9.0.1",
"stylelint-webpack-plugin": "^3.3.0",
"ts-loader": "^9.3.1",
"typescript": "^4.8.2",
"vue": "^3.2.38",
"vue-loader": "^16.8.3"
}

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

View file

@ -1,10 +1,12 @@
{
"/js/preload-back.js": "/js/preload-back.js?id=c608df5583e0193785c2f8fabdc4c33f",
"/js/preload-front.js": "/js/preload-front.js?id=513f40d3fa77933f80bd551b2a5c57ab",
"/css/preload-main.css": "/css/preload-main.css?id=ea5fccf893b13807401d5c307c2456b4",
"/js/back.js": "/js/back.js?id=ed097e1d63457a0991798da99dd30235",
"/js/front.js": "/js/front.js?id=a43a68165b83caa7976e2432f55470d4",
"/css/front.css": "/css/front.css?id=ea02a6cf17b9e9d778518fc6bf388649",
"/css/back.css": "/css/back.css?id=5ab45153bc45216bb1d095c28d3b42df",
"/assets/fonts/Poppins/Poppins-Medium.ttf": "/assets/fonts/Poppins/Poppins-Medium.ttf?id=e791de8a3953f3c23d3198d2d7bd923d",
"/assets/fonts/Poppins/Poppins-Regular.ttf": "/assets/fonts/Poppins/Poppins-Regular.ttf?id=bfa0e348943e04fd8c6202702b1b3e25",
"/assets/fonts/Poppins/Poppins-SemiBold.ttf": "/assets/fonts/Poppins/Poppins-SemiBold.ttf?id=fd8fca9940f16adfc586b42e1c9b6f6f",
"/assets/fonts/Poppins/Poppins-SemiBoldItalic.ttf": "/assets/fonts/Poppins/Poppins-SemiBoldItalic.ttf?id=9466426100d98b856f242f056ff7aab3",
"/assets/fonts/Poppins-Regular.ttf": "/assets/fonts/Poppins-Regular.ttf?id=bfa0e348943e04fd8c6202702b1b3e25"
"/assets/fonts/Poppins-Regular.ttf": "/assets/fonts/Poppins-Regular.ttf?id=bfa0e348943e04fd8c6202702b1b3e25",
"/assets/images/home_logo.png": "/assets/images/home_logo.png?id=70f504c554f866fd6c0d33e6919ac8b8"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View file

@ -1 +0,0 @@
require('./libs/bootstrap');

View file

@ -1,227 +0,0 @@
/*js doc*/
export class Carrousel {
/**
*
* This callback type is called 'requestCallback' and is displayed as a global symbol
*
* @callback moveCallback
* @param {number} index
*/
/**
*
*
* @param {HTMLElement} element
* @param {Object} options
* @param {Object} [options.slidesToScroll=1] Nombre d'éléments à faire défiler
* @param {Object} [options.slidesVisible=1] Nombre d'éléments visible dans un slide
* @param {boolean} [options.loop=false] Doit-on boucler en fin de carrousel
* @param {boolean} [options.pagination=false]
* @param {boolean} [options.navigation=true]
*/
constructor(element, options = {}) {
this.element = element
this.options = Object.assign({}, {
slidesToScroll: 1,
slidesVisible: 1,
loop: true,
play: true,
interval: 3000,
pagination: false,
navigation: true
}, options)
let children = [].slice.call(element.children)
this.isMobile = false
this.currentItem = 0
this.moveCallbacks = []
//Modification du DOM
this.root = this.createDivWithClass('carrousel')
this.container = this.createDivWithClass('carrousel__container')
this.root.setAttribute('tabindex', '0')
this.root.appendChild(this.container)
this.element.appendChild(this.root)
this.items = children.map((child) => {
let item = this.createDivWithClass('carrousel__item')
item.appendChild(child)
this.container.appendChild(item)
return item
})
this.setStyle()
if (this.options.navigation) {
this.createNavigation()
}
if (this.options.pagination) {
this.createPagination()
}
//Evenements
this.moveCallbacks.forEach(cb => cb(0))
this.onWindowResize()
window.addEventListener('resize', this.onWindowResize.bind(this))
this.root.addEventListener('keyup', e => {
if (e.key === 'ArrowRight' || e.key === 'Right') {
this.next()
} else if (e.key === 'ArrowLeft' || e.key === 'Left') {
this.prev()
}
})
// Interval
if (this.options.play) {
let playpause = setInterval(() => this.next(), this.options.interval);
}
}
/**
* Applique les bonnes dimensions aux éléments du carrousel
*/
setStyle() {
let ratio = this.items.length / this.slidesVisible
this.container.style.width = (ratio * 100) + "%"
this.items.forEach(item => item.style.width = ((100 / this.slidesVisible) / ratio) + "%")
}
/**
* Créer les flêches de navigation dans le DOM
*/
createNavigation() {
let nextButton = this.createDivWithClass('carrousel__next')
let prevButton = this.createDivWithClass('carrousel__prev')
this.root.appendChild(nextButton)
this.root.appendChild(prevButton)
nextButton.addEventListener('click', this.next.bind(this))
prevButton.addEventListener('click', this.prev.bind(this))
if (this.options.loop === true) {
return
}
this.onMove(index => {
if (index === 0) {
prevButton.classList.add('carrousel__prev--hidden')
} else {
prevButton.classList.remove('carrousel__prev--hidden')
}
if (this.items[this.currentItem + this.slidesVisible] === undefined) {
nextButton.classList.add('carrousel__next--hidden')
} else {
nextButton.classList.remove('carrousel__next--hidden')
}
})
}
/**
* Créer la pagination dans le DOM
*/
createPagination() {
let pagination = this.createDivWithClass('carrousel__pagination')
let buttons = []
this.root.appendChild(pagination)
for (let i = 0; i < this.items.length; i = i + this.options.slidesToScroll) {
let button = this.createDivWithClass('carrousel__pagination__button')
button.addEventListener('click', () => this.gotoItem(i))
pagination.appendChild(button)
buttons.push(button)
}
this.onMove(index => {
let activeButton = buttons[Math.floor(index / this.options.slidesToScroll)]
if (activeButton) {
buttons.forEach(button => button.classList.remove('carrousel__pagination__button--active'))
activeButton.classList.add('carrousel__pagination__button--active')
}
})
}
next() {
this.gotoItem(this.currentItem + this.slidesToScroll)
}
prev() {
this.gotoItem(this.currentItem - this.slidesToScroll)
}
/**
* Déplace le carrousel vers l'élément ciblé
* @param {number} index
*/
gotoItem(index) {
if (index < 0) {
if (this.options.loop) {
index = this.items.length - this.slidesVisible
} else {
return
}
} else if (index >= this.items.length || (this.items[this.currentItem + this.slidesVisible] === undefined && index > this.currentItem)) {
if (this.options.loop) {
index = 0
} else {
return
}
}
let translateX = index * -100 / this.items.length
this.container.style.transform = 'translate3d(' + translateX + '%, 0, 0)'
this.currentItem = index
this.moveCallbacks.forEach(cb => cb(index))
}
/**
*
* @param {moveCallback} cb
*/
onMove(cb) {
this.moveCallbacks.push(cb)
}
onWindowResize() {
let mobile = window.innerWidth < 800
if (mobile !== this.isMobile) {
this.isMobile = mobile
this.setStyle()
this.moveCallbacks.forEach(cb => cb(this.currentItem))
}
}
/**
*
* @param {string} className
* @returns {HTMLElement}
*/
createDivWithClass(className) {
let div = document.createElement('div')
div.setAttribute('class', className)
return div
}
/**
* @returns {number}
*/
get slidesToScroll() {
return this.isMobile ? 1 : this.options.slidesToScroll
}
/**
* @returns {number}
*/
get slidesVisible() {
return this.isMobile ? 1 : this.options.slidesVisible
}
}
document.addEventListener('DOMContentLoaded', function () {
if (document.querySelector('#carrousel1')) {
new Carrousel(document.querySelector('#carrousel1'), {
pagination: true,
navigation: false,
})
}
if (document.querySelector('#carrousel2')) {
new Carrousel(document.querySelector('#carrousel2'), {})
}
})

View file

@ -1,5 +0,0 @@
import { LdcwebCn } from "./libs/ldcweb-cookies";
window.LdcwebCn = LdcwebCn;
import { Carrousel } from "./components/carousel"
window.Carrousel = Carrousel;

View file

@ -1,28 +0,0 @@
window._ = require('lodash');
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// });

View file

@ -1,401 +0,0 @@
/*
LDC Service Web Cookies
Version 2.0.1
*/
export class LdcwebCn {
constructor(config) {
this.config = config;
this.cookieContainer = document.getElementById("ldcweb-cn");
this.bannerContainer = document.querySelector(".ldcweb-cn-banner");
this.bannerBtn = document.querySelector(".ldcweb-banner-btnDetails-p");
this.ldcwebBtn = document.querySelector(".ldcweb-btn");
this.ldcwebBannerParaP = document.querySelector(".ldcweb-banner-para-p");
this.ldcwebBannerContent = document.querySelector(".ldcweb-banner-content");
this.ldcwebBannerDetails = document.querySelector(".ldcweb-banner-details");
this.ldcwebBannerBtnDetails = document.querySelector(
".ldcweb-banner-btnDetails"
);
this.modalContainer = document.getElementById("ldcweb-cn-modal");
this.acceptAllBtnBanner = document.getElementById(
"ldcweb-cn-accept-banner"
);
this.denyAllBtnBanner = document.getElementById("ldcweb-cn-deny-banner");
this.personalizeBtn = document.getElementsByClassName(
"ldcweb-cn-personalize"
);
this.personalizeBtnBanner = document.querySelector(
".ldcweb-cn-personalize"
);
this.changeBtn = document.getElementsByClassName("ldcweb-cn-change");
this.cookiesList = document.getElementById("ldcweb-cn-list");
this.cookieLink = document.querySelector(".ldcweb-cn-cookie-link");
this.modalDetails = document.querySelector(".modal-details");
this.template = document.getElementById("template").cloneNode(true);
this.modalBtnBoolean = 0;
this.bannerBtnTextBoolean = 0;
document.getElementById("template").remove();
let cookies = this.getLDCWebCookie("ldcwebcn-init");
if (cookies === undefined) {
let newCookie = [];
for (const [key] of Object.entries(this.config)) {
newCookie.push(key + "=wait");
}
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
this.saveLDCWebCookie(newCookie);
} else {
let test = cookies.split(",");
test.forEach((elm) => {
let test = elm.split("=");
if (test[1] === "wait") {
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
}
});
}
let accept = function (e) {
e.preventDefault();
for (const [key, value] of Object.entries(this.config)) {
this.addCookie(key, value);
}
for (let acceptLabel of this.cookieContainer.querySelectorAll(
".accept > label"
)) {
acceptLabel.classList.add("active");
}
for (let denyLabel of this.cookieContainer.querySelectorAll(
".deny > label"
)) {
denyLabel.classList.remove("active");
}
this.updateAllCookiesButtonsActiveStatus();
this.bannerContainer.classList.remove("ldcweb-cn-banner-open");
}.bind(this);
this.acceptAllBtnBanner.addEventListener("click", accept);
let deny = function (e) {
e.preventDefault();
for (const [key, value] of Object.entries(this.config)) {
this.removeCookie(key, value);
}
for (let acceptLabel of this.cookieContainer.querySelectorAll(
".accept > label"
)) {
acceptLabel.classList.remove("active");
}
for (let denyLabel of this.cookieContainer.querySelectorAll(
".deny > label"
)) {
denyLabel.classList.add("active");
}
this.updateAllCookiesButtonsActiveStatus();
this.bannerContainer.classList.remove("ldcweb-cn-banner-open");
}.bind(this);
this.denyAllBtnBanner.addEventListener("click", deny);
let openLdcwebCookies = function (e) {
e.preventDefault();
this.openModal();
}.bind(this);
this.cookieLink.addEventListener("click", openLdcwebCookies);
let hideModal = function (e) {
e.preventDefault();
this.ldcwebBannerContent.classList.toggle("visibility");
this.ldcwebBannerDetails.classList.toggle("visibility");
this.ldcwebBannerBtnDetails.classList.toggle("visibility");
this.modalContainer.classList.toggle("visibility");
this.setCookieList();
}.bind(this);
this.personalizeBtnBanner.addEventListener("click", hideModal);
let changeBtnPersonalize = function (e) {
e.preventDefault();
this.modalDetails.scrollTop = 0;
if (this.modalBtnBoolean === 0) {
this.personalizeBtnBanner.innerHTML =
this.personalizeBtnBanner.getAttribute("data-open-modal");
this.modalBtnBoolean = 1;
} else {
this.personalizeBtnBanner.innerHTML =
this.personalizeBtnBanner.getAttribute("data-close-modal");
this.modalBtnBoolean = 0;
}
}.bind(this);
this.personalizeBtnBanner.addEventListener("click", changeBtnPersonalize);
this.setListenerOnChange();
let cookie = this.getLDCWebCookie("ldcwebcn-init");
let test = cookie.split(",");
test.forEach((elm) => {
let test = elm.split("=");
if (test[1] === "true") {
this.config[test[0]].script();
} else {
if (this.config[test[0]].fallback) {
this.config[test[0]].fallback();
}
}
});
this.updateAllCookiesButtonsActiveStatus();
let changePara = function (e) {
e.preventDefault();
this.ldcwebBannerDetails.classList.toggle("ldcweb-banner-details-open");
this.bannerBtn.classList.toggle("ldcweb-banner-btnDetails-p-open");
if (this.bannerBtnTextBoolean === 0) {
e.target.innerHTML = e.target.getAttribute("data-open");
this.ldcwebBannerParaP.innerHTML =
this.ldcwebBannerParaP.getAttribute("data-open");
this.ldcwebBannerDetails.style.height =
this.ldcwebBannerDetails.children[0].clientHeight + "px";
this.bannerBtnTextBoolean = 1;
} else {
e.target.innerHTML = e.target.getAttribute("data-close");
this.ldcwebBannerParaP.innerHTML =
this.ldcwebBannerParaP.getAttribute("data-close");
this.ldcwebBannerDetails.style.height = "0px";
this.bannerBtnTextBoolean = 0;
}
}.bind(this);
this.bannerBtn.addEventListener("click", changePara);
let resetVue = function (e) {
e.preventDefault();
this.bannerContainer.classList.toggle("ldcweb-cn-banner-open");
if (this.bannerContainer.classList.contains("ldcweb-cn-banner-open")) {
this.ldcwebBannerContent.classList.remove("visibility"),
this.ldcwebBannerDetails.classList.remove("visibility"),
this.ldcwebBannerBtnDetails.classList.remove("visibility"),
this.modalContainer.classList.add("visibility");
this.personalizeBtnBanner.innerHTML =
this.personalizeBtnBanner.getAttribute("data-close-modal");
this.modalBtnBoolean = 0;
}
}.bind(this);
this.ldcwebBtn.addEventListener("click", resetVue);
}
setCookieList() {
this.cookiesList.innerHTML = "";
let cookiesSite = this.getLDCWebCookie("ldcwebcn-init");
let acceptInputEvent = function (acceptLabel, denyLabel, key, value) {
return function () {
acceptLabel.classList.add("active");
denyLabel.classList.remove("active");
this.updateAllCookiesButtonsActiveStatus();
this.addCookie(key, value);
}.bind(this, [acceptLabel, denyLabel, key, value]);
};
let denyInputEvent = function (acceptLabel, denyLabel, key, value) {
return function () {
acceptLabel.classList.remove("active");
denyLabel.classList.add("active");
this.updateAllCookiesButtonsActiveStatus();
this.removeCookie(key, value);
}.bind(this, [acceptLabel, denyLabel, key, value]);
};
for (const [key, value] of Object.entries(this.config)) {
let cookie = document.createElement("li");
cookie.append(this.template.children.item(0).cloneNode(true));
let name = cookie.querySelector("span.ldcweb-cn-name");
let description = cookie.querySelector("span.ldcweb-cn-description");
let link = cookie.querySelector("a.ldcweb-cn-link");
let acceptInput = cookie.querySelector(".accept > input");
let denyInput = cookie.querySelector(".deny > input");
let acceptLabel = cookie.querySelector(".accept > label");
let denyLabel = cookie.querySelector(".deny > label");
name.textContent = value.name;
description.textContent = value.description;
link.textContent = value.labelLink;
link.setAttribute("href", value.link);
acceptInput.id = key + "1";
acceptInput.name = key;
acceptInput.dataset.name = key;
acceptLabel.htmlFor = key + "1";
denyInput.id = key + "2";
denyInput.name = key;
denyInput.dataset.name = key;
denyLabel.htmlFor = key + "2";
acceptInput.addEventListener(
"click",
acceptInputEvent.apply(this, [acceptLabel, denyLabel, key, value])
);
denyInput.addEventListener(
"click",
denyInputEvent.apply(this, [acceptLabel, denyLabel, key, value])
);
this.cookiesList.append(cookie);
let cookiesArray = cookiesSite.split(",");
for (const cookieEl of cookiesArray) {
let name = cookieEl.slice(0, cookieEl.indexOf("="));
let status = cookieEl.slice(cookieEl.indexOf("=") + 1);
if (name === key) {
acceptLabel.classList.remove("active");
denyLabel.classList.remove("active");
switch (status) {
case "true":
acceptLabel.classList.add("active");
break;
case "false":
denyLabel.classList.add("active");
break;
}
}
}
}
this.setListenerOnChange();
}
updateAllCookiesButtonsActiveStatus() {
let acceptsButtons =
this.cookieContainer.querySelectorAll("div.accept > label");
let deniesButtons =
this.cookieContainer.querySelectorAll("div.deny > label");
let activeAcceptsButtons = this.cookieContainer.querySelectorAll(
"div.accept > label.active"
);
let activeDeniesButtons = this.cookieContainer.querySelectorAll(
"div.deny > label.active"
);
if (
acceptsButtons.length &&
acceptsButtons.length === activeAcceptsButtons.length
) {
}
if (
deniesButtons.length &&
deniesButtons.length === activeDeniesButtons.length
) {
}
}
addCookie(key, value) {
if (value.script) {
value.script();
}
this.changeStatus(key, "true");
}
removeCookie(key, value) {
for (let cookieName of value.cookies) {
this.deleteBrowserCookie(cookieName, "/", "." + location.host);
}
if (document.getElementById(key)) {
document.getElementById(key).remove();
}
if (value.fallback) {
value.fallback();
}
this.changeStatus(key, "false");
}
setListenerOnChange() {
this.changeBtn = document.getElementsByClassName("ldcweb-cn-change");
let itemClick = function (item) {
return function () {
this.changeStatus(
item.getAttribute("data-name"),
item.getAttribute("data-status")
);
}.bind(this);
};
for (let item of this.changeBtn) {
this.addEvent(item, "click", itemClick.bind(this, [item]));
}
}
changeStatus(name, status) {
let newCookie = [];
let cookie = this.getLDCWebCookie("ldcwebcn-init");
let test = cookie.split(",");
test.forEach((elm) => {
let test = elm.split("=");
if (test[0] === name) {
newCookie.push(name + "=" + status);
if (status === "false") {
this.config[test[0]].cookies.forEach((elm) => {
let cookies = this.getLDCWebCookie(elm);
if (cookies !== undefined) {
document.cookie =
elm +
"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=" +
document.domain +
"; path=/";
document.cookie =
elm +
"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=." +
document.domain +
"; path=/";
}
});
}
} else {
newCookie.push(elm);
}
});
this.saveLDCWebCookie(newCookie);
}
deleteBrowserCookie(name, path, domain) {
if (this.getLDCWebCookie(name)) {
document.cookie =
name +
"=" +
(path ? ";path=" + path : "") +
(domain ? ";domain=" + domain : "") +
";expires=Thu, 01 Jan 1970 00:00:01 GMT";
}
}
getLDCWebCookie(name) {
let matches = document.cookie.match(
new RegExp(
"(?:^|; )" + name.replace(/([.$?*|{}()[\]\\/+^])/g, "\\$1") + "=([^;]*)"
)
);
return matches ? decodeURIComponent(matches[1]) : undefined;
}
addEvent(element, evnt, funct) {
if (element.attachEvent) return element.attachEvent("on" + evnt, funct);
else return element.addEventListener(evnt, funct, false);
}
saveLDCWebCookie(content) {
let date = new Date();
let newDate = new Date(date.setMonth(date.getMonth() + 13));
document.cookie =
"ldcwebcn-init=" +
content +
"; expires=" +
newDate.toUTCString() +
"; path=/;";
}
openModal() {
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
this.ldcwebBannerContent.classList.add("visibility");
this.ldcwebBannerDetails.classList.add("visibility");
this.ldcwebBannerBtnDetails.classList.add("visibility");
this.modalContainer.classList.remove("visibility");
this.personalizeBtnBanner.innerHTML =
this.personalizeBtnBanner.getAttribute("data-open-modal");
this.modalBtnBoolean = 1;
this.modalDetails.scrollTop = 0;
this.setCookieList();
this.updateAllCookiesButtonsActiveStatus();
}
}

8
resources/sass/back.scss Normal file
View file

@ -0,0 +1,8 @@
@import "bootstrap";
@import "base/bo/base";
@import "partials/bo/header";
@import "partials/bo/footer";
@import "pages/bo/home";

View file

@ -1,129 +0,0 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

View file

@ -1,9 +1,9 @@
$font-path: "~@/fonts";
//CreamyScript Regular
@font-face {
font-display: swap;
font-family: "Poppins";
src: url("#{$font-path}/Poppins/Poppins-Regular.ttf") format("truetype");
font-style: 400;
font-weight: normal;
font-display: swap;
src: url("#{$font-path}/Poppins/Poppins-Regular.ttf") format("truetype");
}

22
resources/sass/front.scss Normal file
View file

@ -0,0 +1,22 @@
@import "utilities/variables";
@import "utilities/functions";
@import "utilities/mixins";
@import "bootstrap";
// ADDITIONAL BOOTSTRAP IMPORTS
@import "vendor/ldcweb-cookies";
@import "base/fo/fonts";
@import "base/fo/base";
@import "partials/fo/header";
@import "partials/fo/footer";
@import "components/buttons";
@import "components/carousel";
@import "components/dropdown";
@import "pages/fo/home";

View file

@ -1,25 +0,0 @@
@import "utilities/variables.scss";
@import "utilities/functions.scss";
@import "utilities/mixins.scss";
@import "libs/bootstrap";
@import "libs-extensions/bootstrap";
@import "base/reset";
@import "base/fonts";
@import "base/base";
@import "partials/bo/header";
@import "partials/bo/footer";
@import "partials/fo/header";
@import "partials/fo/footer";
@import "components/buttons";
@import "components/carousel";
@import "components/dropdown";
@import "pages/bo/home";
@import "pages/fo/home";

View file

@ -0,0 +1,628 @@
/**
* LDC Service Web Cookies
* Version 2.1.0
*/
/* stylelint-disable selector-max-compound-selectors */
/* stylelint-disable max-nesting-depth */
/* DEBUT DU PARAMETRAGE */
/* - Choix des FONTS */
/* - Changement des couleurs et des polices */
/* PARTIE A RENSEIGNER */
$primary-color: rgb(185, 185, 185);
$secondary-color: #0090D7;
$background-color: #282828;
$shadow-color: 0 0.1rem 1rem rgb(0 0 0 / 35%);
$title-font: "Poppins", serif;
$line-height-title: 1;
$title-size: 25px;
$text-font: "Barlow", sans-serif;
$text-size: 14px;
$accept-color: #3a3;
$deny-color: #a33;
/* Position et animation des cookies */
$ldcweb-cn-position-left: 20px; /* Distance par rapport à la gauche de la fenêtre */
$ldcweb-cn-position-right: auto; /* Distance par rapport à la droite de la fenêtre */
$ldcweb-cn-animation-left: 0; /* Position gauche de base des cookies */
$ldcweb-cn-animation-right: auto; /* Position droite de base des cookies */
$ldcweb-cn-position-bottom: 20px; /* Distance par rapport au bas de la fenêtre */
$ldcweb-cn-z-index: 200;
/* PARTIE A RENSEIGNER FACULTATIF */
/* FENETRE D'ACCUEIL */
$ck-bg-color: #161719;
/* Title settings */
$ck-w1-bgcolor-title: $background-color;
$ck-w1-font-family-title: $title-font;
$ck-w1-font-size-title: $title-size;
$ck-w1-color-title: $secondary-color;
/* Text settings */
$ck-w1-font-family-txt: $text-font;
$ck-w1-font-size-txt: $text-size;
$ck-w1-color-txt: $primary-color;
$ck-w1-color-href-hover: $secondary-color;
/* Button settings */
$ck-w1-color-btn: $secondary-color;
$ck-w1-color-btn-hover: $secondary-color;
$ck-w1-font-family-btn-txt: $text-font;
$ck-w1-font-size-btn-txt: $text-size;
$ck-w1-color-btn-txt: #fff;
$ck-w1-color-btn-txt-hover: #fff;
$ck-w1-color-btn-border: transparent;
$ck-w1-color-btn-border-hover: transparent;
/* FENETRE DE PERSONNALISATION */
$ck-bg-color-modal-wrapper: #fff;
/* Title settings */
$ck-w2-bgcolor-title: $background-color;
$ck-w2-font-family-title: $title-font;
$ck-w2-font-size-title: $title-size;
$ck-w2-color-title: $secondary-color;
/* Text settings */
$ck-w2-font-family-txt: $text-font;
$ck-w2-font-size-txt: $text-size;
$ck-w2-color-txt: $primary-color;
$ck-w2-color-href-hover: #000;
/* Accept/Deny btn settings */
$ck-color-accept: #808080;
$ck-color-accept-hover: $accept-color;
$ck-color-deny: #808080;
$ck-color-deny-hover: $deny-color;
$ck-color-txt: #fff;
$ck-color-txt-hover: #fff;
/* Cookies list settings */
$ck-bgcolor-list: #e4e4e4;
$ck-font-family-list: $text-font;
$ck-font-size-list: $text-size;
$ck-color-list: #000;
$ck-color-title: $secondary-color;
/* Scroll bar */
$ck-scroll-bgcolor: $primary-color;
$ck-scroll-barcolor: $secondary-color;
/* FIN DU PARAMETRAGE */
/* MOBILE FIRST */
#template {
display: none;
}
* {
box-sizing: border-box;
&::before {
display: none;
}
}
button {
border: 0;
background-color: transparent;
}
#ldcweb-cn {
&.open-banner {
display: flex;
.ldcweb-cn-banner {
display: flex;
}
}
&.open-modal {
display: flex;
}
p {
color: $ck-w1-color-txt;
font-family: $ck-w1-font-family-txt;
font-size: $ck-w1-font-size-txt;
}
a {
color: $ck-w1-color-txt;
font-family: $ck-w1-font-family-txt;
font-size: $ck-w1-font-size-txt;
text-decoration: underline;
transition: 0s;
}
.ldcweb-cn-banner {
position: fixed;
z-index: $ldcweb-cn-z-index;
right: $ldcweb-cn-animation-right;
bottom: calc($ldcweb-cn-position-bottom + 60px);
left: $ldcweb-cn-animation-left;
display: flex;
overflow: auto;
overflow: hidden;
width: 475px;
height: auto;
max-height: 80vh;
flex-direction: column;
flex-direction: column;
align-items: center;
justify-content: flex-end;
padding: 0;
padding-top: 20px;
margin: 0;
background-color: $ck-bg-color;
border-radius: 10px;
box-shadow: $shadow-color;
line-height: initial;
opacity: 0;
transition: 0.3s;
user-select: none;
visibility: hidden;
&-open {
right: $ldcweb-cn-position-right;
left: $ldcweb-cn-position-left;
opacity: 1;
visibility: visible;
}
}
.ldcweb-banner {
&-img {
display: flex;
width: 150px;
height: auto;
flex-direction: column;
align-items: center;
justify-content: center;
padding-right: 20px;
img {
width: 100%;
}
}
&-text {
flex: 2;
}
&-title {
p {
color: $ck-w1-color-title;
font-family: $ck-w1-font-family-title;
font-size: $ck-w1-font-size-title;
font-weight: bold;
line-height: $line-height-title;
text-align: left;
}
}
&-para-p {
margin: 6px 0;
text-align: justify;
}
&-btn-details {
width: 100%;
margin: 0 0 20px;
}
&-btn-details-p {
width: 100%;
margin: 0 auto;
color: $secondary-color;
cursor: pointer;
font-size: 14px;
text-align: center;
}
&-btns {
display: flex;
width: 100%;
flex: 1;
flex-direction: row;
cursor: pointer;
.ldcweb-banner-btn {
&-flex {
display: flex;
width: 66.5%;
flex-direction: row;
align-items: center;
justify-content: center;
border-top: 1px solid #808080;
text-align: center;
div {
width: 50%;
}
.ldcweb-cn-accept {
color: $secondary-color;
font-weight: bolder;
}
}
&s-btn {
display: flex;
width: 100%;
height: 50px;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: $background-color;
color: $primary-color;
font-family: $ck-w1-font-family-btn-txt;
font-size: $ck-w1-font-size-btn-txt;
text-align: center;
text-decoration: none;
&:hover {
background-color: $ck-w1-color-btn-hover;
color: $ck-w1-color-btn-txt-hover;
}
}
}
}
&-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 20px;
}
&-details {
display: flex;
overflow: hidden;
height: 0;
flex-direction: row;
align-items: center;
align-items: flex-start;
justify-content: center;
padding: 0 20px;
text-align: justify;
transition: 0.3s;
}
&-details-open {
margin-bottom: 6px;
}
&-btn-personalize {
width: 33.5%;
border-top: 1px solid #808080;
}
&-btn-accept {
border-right: 1px solid #808080;
border-left: 1px solid #808080;
}
}
&-modal .modal {
z-index: 200;
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
opacity: 1;
&-wrapper {
position: relative;
display: flex;
overflow: auto;
max-height: 100vh;
flex-direction: column;
align-items: center;
> div {
&:not(:first-of-type) {
width: 100%;
align-items: flex-end;
}
}
}
&-title {
padding: 0 20px;
* {
margin: 0;
text-align: justify;
}
.title {
color: $ck-w2-color-title;
font-family: $ck-w2-font-family-title;
font-size: $ck-w2-font-size-title;
font-weight: bold;
text-align: center;
}
.subtitle {
margin-bottom: 6px;
color: $ck-w2-color-txt;
color: $ck-w2-color-title;
font-family: $ck-w2-font-family-txt;
font-size: $ck-w2-font-size-txt;
text-align: center;
}
.description {
display: flex;
flex-direction: column;
align-items: center;
color: $ck-w2-color-txt;
font-family: $ck-w2-font-family-txt;
font-size: $ck-w2-font-size-txt;
font-weight: normal;
line-height: initial;
}
}
&-btns {
display: flex;
flex-direction: column;
align-items: center;
font-weight: normal;
line-height: initial;
p {
color: $ck-w2-color-txt;
font-family: $ck-w2-font-family-txt;
font-size: $ck-w2-font-size-txt;
}
a {
color: $ck-w2-color-txt;
font-family: $ck-w2-font-family-txt;
font-size: $ck-w2-font-size-txt;
}
}
&-details {
width: 100%;
height: 153px;
margin: 6px 0;
overflow-y: auto;
ul {
display: flex;
flex-direction: column;
padding: 0 20px;
list-style: none;
}
li {
> div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 20px;
border: 1px solid $ck-bgcolor-list;
margin: 10px 0;
border-radius: 20px;
}
span {
color: $ck-color-list;
font-family: $ck-font-family-list;
font-size: $ck-font-size-list;
}
a {
color: $ck-color-list;
font-family: $ck-font-family-list;
font-size: $ck-font-size-list;
}
label {
color: $ck-color-list;
font-family: $ck-font-family-list;
font-size: $ck-font-size-list;
}
}
.ldcweb-cn {
&-name {
color: $ck-color-title;
}
&-infos {
display: flex;
width: 100%;
flex: 1;
flex-direction: column;
span {
&:first-of-type {
font-size: calc($ck-font-size-list * 1.25);
font-weight: bold;
}
}
.ldcweb-cn-description {
color: $ck-w2-color-txt;
}
a {
width: fit-content;
}
}
&-buttons {
display: flex;
width: 200px;
justify-content: space-around;
margin-top: 6px;
div {
display: table;
margin: 0.5em;
text-align: center;
&:first-of-type {
background: $ck-color-accept;
transition: all 0.3s;
input {
&:checked {
~ {
label {
background-color: $ck-color-deny-hover;
}
}
}
~ label.active {
background-color: $ck-color-deny-hover;
}
}
}
&:last-of-type {
background: $ck-color-deny;
transition: all 0.3s;
input {
&:checked {
~ {
label {
background-color: $ck-color-accept-hover;
}
}
}
~ {
label.active {
background-color: $ck-color-accept-hover;
}
}
}
}
}
input {
display: none;
}
label {
display: block;
width: 100px;
padding: 6px 20px;
color: $ck-color-txt;
cursor: pointer;
transition: color 0.3s;
}
}
}
}
}
}
.ldcweb-btn {
position: fixed;
z-index: $ldcweb-cn-z-index;
right: $ldcweb-cn-position-right;
bottom: $ldcweb-cn-position-bottom;
left: $ldcweb-cn-position-left;
width: 50px;
height: 50px;
padding: 8px;
background-color: #fff;
border-radius: 100%;
box-shadow: $shadow-color;
cursor: pointer;
&-icon {
path {
fill: $secondary-color;
}
circle {
fill: $secondary-color;
}
}
}
.visibility {
display: none !important;
}
.btn-autorize {
cursor: pointer;
fill: $secondary-color;
}
.ldcweb-cn-cookie-link {
cursor: pointer;
}
@media (max-width: 535px) {
#ldcweb-cn {
.ldcweb-banner {
&-btns {
flex-direction: column;
.ldcweb-banner-btn-flex {
width: 100%;
.ldcweb-banner-btn-deny {
width: 50%;
}
.ldcweb-banner-btn-accept {
width: 50%;
}
}
.ldcweb-banner-btn-personalize {
width: 100%;
}
}
&-title {
p {
text-align: center;
}
}
&-img {
padding: 0 0 20px;
}
&-btn-accept {
border-right: 0;
border-left: 1px solid #808080;
}
&-details-open {
height: 0;
}
}
.ldcweb-cn-banner {
bottom: 0;
left: 0;
width: 100%;
max-height: 100vh;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
&-content {
flex-direction: column;
}
}
}
}

2
resources/ts/back.ts Normal file
View file

@ -0,0 +1,2 @@
// Bootstrap
import "./libs/bootstrap";

9
resources/ts/front.ts Normal file
View file

@ -0,0 +1,9 @@
// Bootstrap
import "./libs/bootstrap";
// LDCWEB Cookies
import { LdcwebCn } from "./libs/ldcweb-cookies";
window.LdcwebCn = LdcwebCn;
//window.addEventListener("DOMContentLoaded", function () {
//});

View file

@ -0,0 +1 @@
import "bootstrap";

71
resources/ts/libs/index.d.ts vendored Normal file
View file

@ -0,0 +1,71 @@
export {};
import type { LdcwebCn } from "./ldcweb-cookies";
import { AxiosStatic } from "axios";
// * CustomLabel
type SelectModelType = {
color: string;
label: string;
value: string;
};
type EnumType = {
label: string;
value: number | string;
};
// * Recursive List<string>
type StringList = Record<PropertyKey, string>;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface NestedStringListInterface
extends Record<PropertyKey, NestedStringListInterface | StringList> {}
// * Recursive List<number>
type NumberList = Record<PropertyKey, number>;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface NestedNumberListInterface
extends Record<PropertyKey, NestedNumberListInterface | NumberList> {}
// * Recursive List<Model>
type Model = Record<
string,
| string
| boolean
| number
| object
| NestedStringList
| NestedNumberList
| NestedModelInterface
>;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface NestedModelInterface extends Model {}
type NestedStringList = NestedStringListInterface | StringList | string;
type NestedNumberList = NestedNumberListInterface | NumberList | number;
type ModelList = Array<Model>;
declare global {
type CustomTag = LaravelModel;
type LaravelModel = Model;
type LaravelModelList = ModelList;
type SelectModel = SelectModelType;
type Enum = EnumType;
interface Window {
$displayMenu: (show: boolean) => void;
$toggleBasketMenu: () => void;
LdcwebCn: LdcwebCn | {};
axios: AxiosStatic;
__SESSION_WATCH: Record<string, unknown>;
__SYSTEM: {
_asset: string;
_locale: string;
_routes: Record<string, string>;
_translations: {
json: NestedStringList;
php: NestedStringList;
};
};
}
}

View file

@ -0,0 +1,589 @@
/**
* LDC Service Web Cookies
* Version 2.1.0
*/
enum LdcwebCookieStatus {
true = "true",
false = "false",
wait = "wait",
}
type LdcwebCookieStatusString = keyof typeof LdcwebCookieStatus;
type LdcwebCnOptions = {
name: string;
description: string;
link: string;
labelLink: string;
cookies: string[];
/**
* Fonction qui sert à initialiser la fonctionnalité
* conduisant à la génération du cookie
* @return void
*/
script: () => void;
/**
* Fonction qui sert à informer l'utilisateur
* sur chaque élèment que le cookie
* associé à la fonctionnalité
* est désactivé et propose un lien sur
* cookie notice pour l'activer
* @return void
*/
fallback: () => void | null;
};
export class LdcwebCn {
config: Record<string, LdcwebCnOptions>;
cookieContainer: HTMLDivElement;
bannerContainer: HTMLDivElement;
bannerBtn: HTMLButtonElement;
ldcwebBtn: HTMLButtonElement;
ldcwebBannerParaP: HTMLParagraphElement;
ldcwebBannerContent: HTMLDivElement;
ldcwebBannerDetails: HTMLDivElement;
ldcwebBannerBtnDetails: HTMLDivElement;
modalContainer: HTMLDivElement;
acceptAllBtnBanner: HTMLButtonElement;
denyAllBtnBanner: HTMLButtonElement;
personalizeBtnBanner: HTMLButtonElement;
changeBtn: HTMLCollectionOf<HTMLElement>;
cookiesList: HTMLUListElement;
cookieLink: HTMLElement;
modalDetails: HTMLDivElement;
template: HTMLDivElement;
modalBtnBoolean: boolean;
bannerBtnTextBoolean: boolean;
constructor(config: Record<string, LdcwebCnOptions>) {
// * INITIALIZE VARS
this.config = config;
let cookieContainer: HTMLDivElement | null = null;
if (!(cookieContainer = document.querySelector("#ldcweb-cn"))) {
throw new Error("Cannot find #ldcweb-cn");
}
this.cookieContainer = cookieContainer;
this.bannerContainer = document.querySelector(
".ldcweb-cn-banner"
) as HTMLDivElement;
this.bannerBtn = document.querySelector(
"button.ldcweb-banner-btn-details-p"
) as HTMLButtonElement;
this.ldcwebBtn = document.querySelector(
"button.ldcweb-btn"
) as HTMLButtonElement;
this.ldcwebBannerParaP = document.querySelector(
".ldcweb-banner-para-p"
) as HTMLParagraphElement;
this.ldcwebBannerContent = document.querySelector(
".ldcweb-banner-content"
) as HTMLDivElement;
this.ldcwebBannerDetails = document.querySelector(
".ldcweb-banner-details"
) as HTMLDivElement;
this.ldcwebBannerBtnDetails = document.querySelector(
".ldcweb-banner-btn-details"
) as HTMLDivElement;
this.modalContainer = document.getElementById(
"ldcweb-cn-modal"
) as HTMLDivElement;
this.acceptAllBtnBanner = document.getElementById(
"ldcweb-cn-accept-banner"
) as HTMLButtonElement;
this.denyAllBtnBanner = document.getElementById(
"ldcweb-cn-deny-banner"
) as HTMLButtonElement;
this.personalizeBtnBanner = document.querySelector(
".ldcweb-cn-personalize"
) as HTMLButtonElement;
this.changeBtn = document.getElementsByClassName(
"ldcweb-cn-change"
) as HTMLCollectionOf<HTMLElement>;
this.cookiesList = document.getElementById(
"ldcweb-cn-list"
) as HTMLUListElement;
this.cookieLink = document.querySelector(
".ldcweb-cn-cookie-link"
) as HTMLAnchorElement;
this.modalDetails = document.querySelector(
".modal-details"
) as HTMLDivElement;
this.modalBtnBoolean = false;
this.bannerBtnTextBoolean = false;
let template: HTMLDivElement | null = null;
if (!(template = document.querySelector("#template"))) {
throw new Error("Cannot find 'template' element");
}
this.template = template;
const memoryTemplate = this.template.cloneNode(true) as HTMLDivElement;
this.template.remove();
this.template = memoryTemplate;
// * LOGIC
const self = this;
const cookies = this.getLDCWebCookie("ldcwebcn-init");
if (cookies === undefined) {
const newCookie: string[] = [];
for (const [key] of Object.entries(this.config)) {
newCookie.push(key + "=wait");
}
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
this.saveLDCWebCookie(newCookie.join(","));
} else {
const test = cookies.split(",");
test.forEach((elm) => {
const test = elm.split("=");
if (test[1] === "wait") {
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
}
});
}
/**
* Accept a specific cookie
*/
const accept = function (e: { preventDefault: () => void }) {
e.preventDefault();
for (const [key, value] of Object.entries(self.config)) {
self.addCookie(key, value);
}
for (const acceptLabel of self.cookieContainer.querySelectorAll(
".accept > label"
)) {
acceptLabel.classList.add("active");
}
for (const denyLabel of self.cookieContainer.querySelectorAll(
".deny > label"
)) {
denyLabel.classList.remove("active");
}
self.bannerContainer.classList.remove("ldcweb-cn-banner-open");
}.bind(this);
this.acceptAllBtnBanner.addEventListener("click", accept);
/**
* Deny a specific cookie
*/
const deny = function (e: { preventDefault: () => void }) {
e.preventDefault();
for (const [key, value] of Object.entries(self.config)) {
self.removeCookie(key, value);
}
for (const acceptLabel of self.cookieContainer.querySelectorAll(
".accept > label"
)) {
acceptLabel.classList.remove("active");
}
for (const denyLabel of self.cookieContainer.querySelectorAll(
".deny > label"
)) {
denyLabel.classList.add("active");
}
self.bannerContainer.classList.remove("ldcweb-cn-banner-open");
}.bind(this);
this.denyAllBtnBanner.addEventListener("click", deny);
const openLdcwebCookies = function (e: { preventDefault: () => void }) {
e.preventDefault();
self.openModal();
}.bind(this);
this.cookieLink.addEventListener("click", openLdcwebCookies);
/**
* Show the modal with the list of all cookies
*/
const hideModal = function (e: { preventDefault: () => void }) {
e.preventDefault();
self.ldcwebBannerContent.classList.toggle("visibility");
self.ldcwebBannerDetails.classList.toggle("visibility");
self.ldcwebBannerBtnDetails.classList.toggle("visibility");
self.modalContainer.classList.toggle("visibility");
self.setCookieList();
}.bind(this);
this.personalizeBtnBanner.addEventListener("click", hideModal);
this.personalizeBtnBanner.addEventListener("click", (e) => {
e.preventDefault();
self.modalDetails.scrollTop = 0;
if (!self.modalBtnBoolean) {
if (!self.personalizeBtnBanner.dataset.openModal) {
throw new Error("Cannot find attribute data-open-modal");
}
self.personalizeBtnBanner.innerHTML =
self.personalizeBtnBanner.dataset.openModal;
self.modalBtnBoolean = true;
} else {
if (!self.personalizeBtnBanner.dataset.closeModal) {
throw new Error("Cannot find attribute data-close-modal");
}
self.personalizeBtnBanner.innerHTML =
self.personalizeBtnBanner.dataset.closeModal;
self.modalBtnBoolean = false;
}
});
this.setListenerOnChange();
const cookie = this.getLDCWebCookie("ldcwebcn-init");
if (cookie === undefined) {
throw Error("Ldcweb cookie is not set");
}
const test = cookie.split(",");
test.forEach((elm) => {
const test = elm.split("=");
if (test[1] === "true") {
this.config[test[0]].script();
} else {
if (this.config[test[0]].fallback != null) {
this.config[test[0]].fallback();
}
}
});
this.bannerBtn.addEventListener("click", (e: MouseEvent) => {
self.ldcwebBannerDetails.classList.toggle(
"ldcweb-banner-details-open"
);
self.bannerBtn.classList.toggle("ldcweb-banner-btn-details-p-open");
if (!self.bannerBtn.dataset.open || !self.bannerBtn.dataset.close) {
throw new Error(
"Cannot find attribute data-open or data-close"
);
}
if (
!self.ldcwebBannerParaP.dataset.open ||
!self.ldcwebBannerParaP.dataset.close
) {
throw new Error(
"Cannot find attribute data-open or data-close"
);
}
if (self.bannerBtnTextBoolean) {
self.bannerBtn.innerHTML = self.bannerBtn.dataset.close;
self.ldcwebBannerParaP.innerHTML =
self.ldcwebBannerParaP.dataset.close;
self.ldcwebBannerDetails.style.height = "0px";
self.bannerBtnTextBoolean = false;
} else {
self.bannerBtn.innerHTML = self.bannerBtn.dataset.open;
self.ldcwebBannerParaP.innerHTML =
self.ldcwebBannerParaP.dataset.open;
self.ldcwebBannerDetails.style.height =
self.ldcwebBannerDetails.children[0].clientHeight + "px";
self.bannerBtnTextBoolean = true;
}
});
/**
* Show the default vue of the cookies modal
*/
const resetVue = function (e: { preventDefault: () => void }) {
e.preventDefault();
self.bannerContainer.classList.toggle("ldcweb-cn-banner-open");
if (
self.bannerContainer.classList.contains("ldcweb-cn-banner-open")
) {
self.ldcwebBannerContent.classList.remove("visibility");
self.ldcwebBannerDetails.classList.remove("visibility");
self.ldcwebBannerBtnDetails.classList.remove("visibility");
self.modalContainer.classList.add("visibility");
if (!self.personalizeBtnBanner.dataset.closeModal) {
throw new Error("Cannot find attribut data-close-modal");
}
self.personalizeBtnBanner.innerHTML =
self.personalizeBtnBanner.dataset.closeModal;
self.modalBtnBoolean = false;
}
}.bind(this);
this.ldcwebBtn.addEventListener("click", resetVue);
}
/**
* Set the cookies list in the modal
*/
setCookieList() {
const self = this;
this.cookiesList.innerHTML = "";
for (const [key, value] of Object.entries(this.config)) {
const cookie = document.createElement("li");
const childItem = this.template.children.item(
0
) as HTMLDivElement | null;
if (childItem === null) {
throw new Error("Cannot find child item");
}
cookie.append(childItem.cloneNode(true));
const name = cookie.querySelector(
"span.ldcweb-cn-name"
) as HTMLSpanElement;
const description = cookie.querySelector(
"span.ldcweb-cn-description"
) as HTMLSpanElement;
const link = cookie.querySelector(
"a.ldcweb-cn-link"
) as HTMLButtonElement;
const acceptInput = cookie.querySelector(
".accept > input"
) as HTMLInputElement;
const denyInput = cookie.querySelector(
".deny > input"
) as HTMLInputElement;
const acceptLabel = cookie.querySelector(
".accept > label"
) as HTMLLabelElement;
const denyLabel = cookie.querySelector(
".deny > label"
) as HTMLLabelElement;
name.textContent = value.name;
description.textContent = value.description;
link.textContent = value.labelLink;
link.setAttribute("href", value.link);
acceptInput.id = key + "1";
acceptInput.name = key;
acceptInput.dataset.name = key;
acceptLabel.htmlFor = key + "1";
denyInput.id = key + "2";
denyInput.name = key;
denyInput.dataset.name = key;
denyLabel.htmlFor = key + "2";
acceptInput.addEventListener("click", () => {
acceptLabel.classList.add("active");
denyLabel.classList.remove("active");
self.addCookie(key, value);
});
denyInput.addEventListener("click", () => {
acceptLabel.classList.remove("active");
denyLabel.classList.add("active");
self.removeCookie(key, value);
});
this.cookiesList.append(cookie);
const cookiesSite = this.getLDCWebCookie("ldcwebcn-init");
if (cookiesSite === undefined) {
throw Error("Ldcweb cookie is not set");
}
const cookiesArray = cookiesSite.split(",");
for (const cookieEl of cookiesArray) {
const name = cookieEl.slice(0, cookieEl.indexOf("="));
const status = cookieEl.slice(cookieEl.indexOf("=") + 1);
if (name === key) {
acceptLabel.classList.remove("active");
denyLabel.classList.remove("active");
switch (status) {
case "true":
acceptLabel.classList.add("active");
break;
case "false":
denyLabel.classList.add("active");
break;
}
}
}
}
this.setListenerOnChange();
}
/**
* Add a specific cookie and
* change his status to true
*
* @param key
* @param value
*/
addCookie(key: string, value: LdcwebCnOptions) {
if (value.script) {
value.script();
}
this.changeStatus(key, "true");
}
/**
* Remove a specific cookie and
* change his status to false
*
* @param key
* @param value
*/
removeCookie(key: string, value: LdcwebCnOptions) {
for (const cookieName of value.cookies) {
this.deleteBrowserCookie(cookieName, "/", "." + location.host);
}
const cookieName = document.getElementById(key);
if (cookieName) {
cookieName.remove();
}
if (value.fallback) {
value.fallback();
}
this.changeStatus(key, "false");
}
/**
* Add events for each cookie buttons
* Activate or Deactivate a specific cookie
*/
setListenerOnChange() {
const self = this;
this.changeBtn = document.getElementsByClassName(
"ldcweb-cn-change"
) as HTMLCollectionOf<HTMLElement>;
for (const item of this.changeBtn) {
this.addEvent(item, "click", () => {
if (!item.dataset.name) {
throw new Error("Dataset is missing required elements");
}
const status = item.dataset.status as
| LdcwebCookieStatus
| undefined;
if (!status || !(status in LdcwebCookieStatus)) {
throw new Error("Dataset is missing required elements");
}
self.changeStatus(item.dataset.name, status);
});
}
}
/**
* Change the status of a cookie
*
* @param name
* @param status
*/
changeStatus(name: string, status: LdcwebCookieStatusString) {
/** Contains array of string like youtube=true etc */
const newCookie: string[] = [];
const cookie = this.getLDCWebCookie("ldcwebcn-init");
if (cookie === undefined) {
throw Error("Ldcweb cookie is not set");
}
/** specificCookieString contains youtube=true like */
cookie.split(",").forEach((specificCookieString) => {
/** Contanins cookie name 0 and cookie value 1 */
const test = specificCookieString.split("=");
// Check this cookie is the one to update
if (test[0] === name) {
newCookie.push(name + "=" + status);
if (status === "false") {
// * Iterer sur chque cookie possible de la config
this.config[test[0]].cookies.forEach(
(cookieNametoRemove) => {
const cookies =
this.getLDCWebCookie(cookieNametoRemove);
// * Si le navigateur possede le cookie
if (cookies !== undefined) {
// * Suppression du cookie et de sa version precedé dun point
document.cookie =
cookieNametoRemove +
"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=" +
document.domain +
"; path=/";
document.cookie =
cookieNametoRemove +
"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=." +
document.domain +
"; path=/";
}
}
);
}
} else {
newCookie.push(specificCookieString);
}
});
this.saveLDCWebCookie(newCookie.join(","));
}
/**
* Set an older expire parameter to a specific cookie
*
* @param name
* @param path
* @param domain
*/
deleteBrowserCookie(name: string, path: string, domain: string) {
if (this.getLDCWebCookie(name)) {
document.cookie =
name +
"=" +
(path ? ";path=" + path : "") +
(domain ? ";domain=" + domain : "") +
";expires=Thu, 01 Jan 1970 00:00:01 GMT";
}
}
/**
* Get the Ldcweb cookie
*
* @param name
* @returns A string like analytics=true,youtube=true or undefined
*/
getLDCWebCookie(name: string) {
const matches = document.cookie.match(
new RegExp(
"(?:^|; )" +
name.replace(/([.$?*|{}()[\]\\/+^])/g, "\\$1") +
"=([^;]*)"
)
);
return matches ? decodeURIComponent(matches[1]) : undefined;
}
/**
* Add event on a specific element
*
* @param element
* @param evnt
* @param funct
* @returns
*/
addEvent(element: HTMLElement, evnt: string, funct: () => void) {
return element.addEventListener(evnt, funct, false);
}
/**
* Save cookie content on web browser
*
* @param content
*/
saveLDCWebCookie(content: string) {
const date = new Date();
const newDate = new Date(date.setMonth(date.getMonth() + 13));
document.cookie =
"ldcwebcn-init=" +
content +
"; expires=" +
newDate.toUTCString() +
"; path=/;";
}
/**
* Open the cookies modal
*/
openModal() {
this.bannerContainer.classList.add("ldcweb-cn-banner-open");
this.ldcwebBannerContent.classList.add("visibility");
this.ldcwebBannerDetails.classList.add("visibility");
this.ldcwebBannerBtnDetails.classList.add("visibility");
this.modalContainer.classList.remove("visibility");
this.personalizeBtnBanner.innerHTML =
this.personalizeBtnBanner.dataset?.closeModal ?? "PERSONNALISER";
this.modalBtnBoolean = true;
// Scroll to the top of the cookies list
this.modalDetails.scrollTop = 0;
this.setCookieList();
}
}

View file

@ -0,0 +1,26 @@
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
@include('fo.partials.head')
@stack('styles')
</head>
<body>
<div id="app">
@include('fo.partials.header')
<main>
@yield('content')
</main>
@include('fo.partials.footer')
</div>
@include('fo.libs.ldcweb-cookies')
</body>
<!-- Scripts -->
<script type="text/javascript" src="{{ asset('js/front.js') }}"></script>
@stack('scripts')
</html>

View file

@ -0,0 +1,199 @@
<!--
* LDC Service Web Cookies
* Version 2.1.0
-->
<div id="ldcweb-cn">
<button class="ldcweb-btn" title="Personnaliser les cookies">
<svg class="ldcweb-btn-icon" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M14.0001 2.93383C14.0001 4.16622 14.6159 5.25477 15.5567 5.90849C15.3526 6.46423 15.2412 7.06473 15.2412 7.69126C15.2412 10.5472 17.5564 12.8624 20.4123 12.8624C21.0807 12.8624 21.7195 12.7356 22.3059 12.5047C22.9456 13.527 24.0817 14.2069 25.3766 14.2069C26.1872 14.2069 26.9357 13.9404 27.539 13.4903C27.5453 13.6594 27.5484 13.8294 27.5484 14C27.5484 21.4826 21.4826 27.5484 14 27.5484C6.51748 27.5484 0.45166 21.4826 0.45166 14C0.45166 6.51748 6.51748 0.45166 14 0.45166C14.3209 0.45166 14.6391 0.462811 14.9543 0.484747C14.3618 1.12929 14.0001 1.98931 14.0001 2.93383ZM21.2176 2.53212C21.2195 2.54914 21.2213 2.56619 21.2229 2.58328C21.2569 2.58864 21.2909 2.59433 21.3247 2.60035C21.2891 2.57745 21.2534 2.5547 21.2176 2.53212ZM25.5171 6.86104C25.523 6.89745 25.5285 6.93399 25.5336 6.97066C25.5512 6.97141 25.5687 6.97228 25.5861 6.97328C25.5633 6.93574 25.5403 6.89833 25.5171 6.86104ZM12.5247 2.09283C12.4748 2.38291 12.4487 2.68118 12.4487 2.98553C12.4487 4.33316 12.9591 5.56158 13.7972 6.48802C13.7266 6.87842 13.6898 7.28054 13.6898 7.69126C13.6898 11.404 16.6996 14.4137 20.4123 14.4137C20.8725 14.4137 21.3219 14.3675 21.7562 14.2794C22.689 15.1941 23.9669 15.7582 25.3766 15.7582C25.5439 15.7582 25.7094 15.7503 25.8726 15.7347C25.0321 21.5385 20.0368 25.9971 14.0001 25.9971C7.37431 25.9971 2.00305 20.6258 2.00305 14.0001C2.00305 7.87378 6.59498 2.82 12.5247 2.09283Z"
fill="#FF4E4E" />
<circle cx="7.58784" cy="12.8624" r="1.96503" fill="#FF4E4E" />
<circle cx="8.82887" cy="19.2745" r="1.3445" fill="#FF4E4E" />
<circle cx="13.6897" cy="14.5171" r="1.03423" fill="#FF4E4E" />
<circle cx="11.4144" cy="7.48439" r="0.930805" fill="#FF4E4E" />
<circle cx="17.5164" cy="20.3089" r="1.86161" fill="#FF4E4E" />
<circle cx="21.3432" cy="6.7604" r="0.930805" fill="#FF4E4E" />
<circle cx="22.1706" cy="1.89958" r="1.44792" fill="#FF4E4E" />
<circle cx="26.8245" cy="8.31185" r="0.72396" fill="#FF4E4E" />
</svg>
</button>
<div id="ldcweb-banner" class="ldcweb-cn-banner">
<div class="ldcweb-banner-content">
<div class="ldcweb-banner-img">
<img src="{{ asset('assets/images/home_logo.png') }}" alt="Logo" />
</div>
<div class="ldcweb-banner-text">
<div class="ldcweb-banner-title">
<p aria-level="h1">Le site internet Le Gaulois Professionnel utilise des cookies !</p>
</div>
<p class="ldcweb-banner-para-p" data-open="Ce site web stocke les cookies sur votre ordinateur. Le Gaulois Professionnel utilise ces informations
afin d’améliorer et de personnaliser votre expérience de navigation, ainsi que pour l'analyse et les indicateurs concernant nos
visiteurs à la fois sur ce site web et sur d'autres supports. Vous pouvez cliquer sur « Accepter » si vous consentez à l’utilisation
de ces cookies." data-close="Nous utilisons des cookies pour nous assurer du bon fonctionnement de notre site et à des fins analytiques.
En poursuivant votre navigation sur ce site ou en fermant ce bandeau, vous consentez à l’utilisation de ces
cookies.">Nous utilisons des cookies pour nous assurer du bon fonctionnement de notre site et à des
fins analytiques.
En poursuivant votre navigation sur ce site ou en fermant ce bandeau, vous consentez à l’utilisation
de ces
cookies.</p>
</div>
</div>
<div class="ldcweb-banner-details">
<p>Si vous refusez l'utilisation des cookies, vos informations ne seront pas suivies lors de votre visite
sur ce site. Un cookie sera utilisé
dans votre navigateur afin de se souvenir de ne pas suivre vos préférences. Certaines fonctionnalités ne
seront pas accessibles.
Vous pouvez changer d’avis et modifier votre consentement à tout moment en revenant sur ce site.
Pour en savoir plus sur les cookies que nous utilisons, consultez notre <a href="{{ route('policies') }}">charte de
confidentialité</a>.</p>
</div>
<div class="ldcweb-banner-btn-details">
<button class="ldcweb-banner-btn-details-p" data-open="Moins de détails..."
data-close="Plus de détails...">Plus
de détails...</button>
</div>
<div id="ldcweb-cn-modal" class="visibility">
<div class="modal-wrapper">
<div class="modal-title">
<p class="title" aria-level="h2">{{__('Panneau de gestion des cookies') }}</p>
<p class="subTitle">{{ __('Le respect de votre vie privée est notre priorité') }}</p>
<p class="description">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.</p>
</div>
<div class="modal-details">
<ul id="ldcweb-cn-list">
</ul>
<div id="template">
<div>
<div class="ldcweb-cn-infos">
<span class="ldcweb-cn-name">Google Analytics (universal)</span>
<span class="ldcweb-cn-description">Ce service peut déposer 8 cookies.</span>
<a class="ldcweb-cn-link" href="#">En savoir plus</button>
</div>
<div class="ldcweb-cn-buttons">
<div class="deny" id="deny-btn">
<input type="radio" id="analytics2" name="analytics" data-name="analytics"
data-status="false">
<label for="analytics2">{{ __('Interdire') }}</label>
</div>
<div class="accept" id="accept-btn">
<input type="radio" id="analytics1" name="analytics" data-name="analytics"
data-status="true">
<label for="analytics1">{{ __('Autoriser') }}</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="ldcweb-banner-btns">
<div class="ldcweb-banner-btn-flex">
<div class="ldcweb-banner-btn-deny">
<a id="ldcweb-cn-deny-banner" class="ldcweb-banner-btns-btn ldcweb-cn-deny">TOUT REFUSER</a>
</div>
<div class="ldcweb-banner-btn-accept">
<a id="ldcweb-cn-accept-banner" class="ldcweb-banner-btns-btn ldcweb-cn-accept">TOUT ACCEPTER</a>
</div>
</div>
<div class="ldcweb-banner-btn-personalize">
<a class="ldcweb-banner-btns-btn ldcweb-cn-personalize" data-open-modal="RETOUR"
data-close-modal="PERSONNALISER">PERSONNALISER</a>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
window.LDCWebCN = new LdcwebCn({
'recaptcha': {
'name': "API - reCAPTACHA",
'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.',
'link': 'https://policies.google.com/privacy',
'labelLink': 'En savoir plus',
'cookies': ['NID', '__Secure-3PAPISID', '__Secure-3PSID', '__Secure-3PSIDCC'],
'script': function () {
(function (d, t) {
let g = d.createElement(t), s = d.getElementsByTagName(t)[0];
g.src = 'https://www.google.com/recaptcha/api.js?render=6LePZvAUAAAAABs8uGHxhSkJVPVs4yCJ3amJ1HpX';
s.parentNode.insertBefore(g, s)
}(document, 'script'));
}
},
'analytics': {
'name': "MESURES D'AUDIENCE - Google Analytics",
'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 savoir +',
'link': 'https://support.google.com/analytics/answer/6004245',
'cookies': ['_ga', '_gat_gtag_{{ str_replace("-","_", config('google.analyticsKey')) }}', '_gid'],
'script': function () {
(function (d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src = 'https://www.googletagmanager.com/gtag/js?id={{config('google.analyticsKey')}}';
g.id = 'analytics';
s.parentNode.insertBefore(g, s)
}(document, 'script'));
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', '{{config('google.analyticsKey')}}');
}
},
'youtube': {
'name': "VIDEOS - Youtube",
'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://policies.google.com/technologies/cookies?hl=fr&utm_source=ucb',
'labelLink': 'En savoir plus',
'cookies': ['NID', 'VISITOR_INFO1_LIVE', 'YSC'],
'script': function () {
let youtubeVids = document.getElementsByClassName('ldcweb-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;
e.width = "640";
e.height = "360";
e.frameBorder = "0";
e.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
e.allowFullscreen = true;
item.innerHTML = "";
item.appendChild(e);
}
},
fallback: function () {
let youtubeVids = document.getElementsByClassName('ldcweb-cn-youtube');
for (let item of youtubeVids) {
let a = document.createElement('a');
a.innerText = 'Autoriser';
a.classList.add('ldcweb-cn-cookie-link');
a.classList.add('btn-autorize');
a.onclick = function () {
LdcwebCn.openModal();
};
let e = document.createElement('p');
e.innerHTML = 'Youtube est désactivé. ';
item.innerHTML = "";
e.appendChild(a);
item.appendChild(e);
}
}
}
});
</script>
@endpush

View file

@ -0,0 +1,13 @@
@section('title', "titre de la homepage")
@section('description', "description de la homepage")
@section('keywords', "Mots clé de la homepage")
@extends('../fo.frontend')
@section('content')
<div class="container home">
<p>main content</p>
</div>
@endsection

View file

@ -0,0 +1,6 @@
<footer>
<div>
<p>footer content</p>
<a href="#cookies" class="ldcweb-cn-cookie-link">Gestion des cookies</a>
</div>
</footer>

View file

@ -0,0 +1,23 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="stylesheet" href="{{ mix('css/front.css') }}">
<title>@hasSection('title')@yield('title')@else{{ config('app.name') }}@endif</title>
@hasSection('description')<meta name="description" content="@yield('description')">@endif
@hasSection('keywords')<meta name="keywords" content="@yield('keywords')">@endif
@hasSection('canonical')
<link rel="canonical" href="@yield('canonical')" />
@else
<link rel="canonical" href="{{ url()->current() }}" />
@endif
<!-- META INDEX, FOLLOW -->
@hasSection('metaIndex')
<meta name="robots" content="@yield('metaIndex')">
@else
<meta name="robots" content="index, follow">
@endif

View file

@ -0,0 +1,3 @@
<header>
<p>header content</p>
</header>

View file

@ -1,132 +0,0 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
<!-- Styles -->
<style>
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.dark\:text-gray-500{--tw-text-opacity:1;color:#6b7280;color:rgba(107,114,128,var(--tw-text-opacity))}}
</style>
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
</head>
<body class="antialiased">
<div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
@if (Route::has('login'))
<div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
@auth
<a href="{{ url('/home') }}" class="text-sm text-gray-700 dark:text-gray-500 underline">Home</a>
@else
<a href="{{ route('login') }}" class="text-sm text-gray-700 dark:text-gray-500 underline">Log in</a>
@if (Route::has('register'))
<a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 dark:text-gray-500 underline">Register</a>
@endif
@endauth
</div>
@endif
<div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
<div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
<svg viewBox="0 0 651 192" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto text-gray-700 sm:h-20">
<g clip-path="url(#clip0)" fill="#EF3B2D">
<path d="M248.032 44.676h-16.466v100.23h47.394v-14.748h-30.928V44.676zM337.091 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.431 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162-.001 2.863-.479 5.584-1.432 8.161zM463.954 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.432 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162 0 2.863-.479 5.584-1.432 8.161zM650.772 44.676h-15.606v100.23h15.606V44.676zM365.013 144.906h15.607V93.538h26.776V78.182h-42.383v66.724zM542.133 78.182l-19.616 51.096-19.616-51.096h-15.808l25.617 66.724h19.614l25.617-66.724h-15.808zM591.98 76.466c-19.112 0-34.239 15.706-34.239 35.079 0 21.416 14.641 35.079 36.239 35.079 12.088 0 19.806-4.622 29.234-14.688l-10.544-8.158c-.006.008-7.958 10.449-19.832 10.449-13.802 0-19.612-11.127-19.612-16.884h51.777c2.72-22.043-11.772-40.877-33.023-40.877zm-18.713 29.28c.12-1.284 1.917-16.884 18.589-16.884 16.671 0 18.697 15.598 18.813 16.884h-37.402zM184.068 43.892c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002-35.648-20.524a2.971 2.971 0 00-2.964 0l-35.647 20.522-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v38.979l-29.706 17.103V24.493a3 3 0 00-.103-.776c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002L40.098 1.396a2.971 2.971 0 00-2.964 0L1.487 21.919l-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v122.09c0 1.063.568 2.044 1.489 2.575l71.293 41.045c.156.089.324.143.49.202.078.028.15.074.23.095a2.98 2.98 0 001.524 0c.069-.018.132-.059.2-.083.176-.061.354-.119.519-.214l71.293-41.045a2.971 2.971 0 001.489-2.575v-38.979l34.158-19.666a2.971 2.971 0 001.489-2.575V44.666a3.075 3.075 0 00-.106-.774zM74.255 143.167l-29.648-16.779 31.136-17.926.001-.001 34.164-19.669 29.674 17.084-21.772 12.428-43.555 24.863zm68.329-76.259v33.841l-12.475-7.182-17.231-9.92V49.806l12.475 7.182 17.231 9.92zm2.97-39.335l29.693 17.095-29.693 17.095-29.693-17.095 29.693-17.095zM54.06 114.089l-12.475 7.182V46.733l17.231-9.92 12.475-7.182v74.537l-17.231 9.921zM38.614 7.398l29.693 17.095-29.693 17.095L8.921 24.493 38.614 7.398zM5.938 29.632l12.475 7.182 17.231 9.92v79.676l.001.005-.001.006c0 .114.032.221.045.333.017.146.021.294.059.434l.002.007c.032.117.094.222.14.334.051.124.088.255.156.371a.036.036 0 00.004.009c.061.105.149.191.222.288.081.105.149.22.244.314l.008.01c.084.083.19.142.284.215.106.083.202.178.32.247l.013.005.011.008 34.139 19.321v34.175L5.939 144.867V29.632h-.001zm136.646 115.235l-65.352 37.625V148.31l48.399-27.628 16.953-9.677v33.862zm35.646-61.22l-29.706 17.102V66.908l17.231-9.92 12.475-7.182v33.841z"/>
</g>
</svg>
</div>
<div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
<div class="grid grid-cols-1 md:grid-cols-2">
<div class="p-6">
<div class="flex items-center">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">Documentation</a></div>
</div>
<div class="ml-12">
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
</div>
</div>
</div>
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-t-0 md:border-l">
<div class="flex items-center">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"></path><path d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laracasts.com" class="underline text-gray-900 dark:text-white">Laracasts</a></div>
</div>
<div class="ml-12">
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
</div>
</div>
</div>
<div class="p-6 border-t border-gray-200 dark:border-gray-700">
<div class="flex items-center">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path></svg>
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel-news.com/" class="underline text-gray-900 dark:text-white">Laravel News</a></div>
</div>
<div class="ml-12">
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
</div>
</div>
</div>
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-l">
<div class="flex items-center">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<div class="ml-4 text-lg leading-7 font-semibold text-gray-900 dark:text-white">Vibrant Ecosystem</div>
</div>
<div class="ml-12">
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
Laravel's robust library of first-party tools and libraries, such as <a href="https://forge.laravel.com" class="underline">Forge</a>, <a href="https://vapor.laravel.com" class="underline">Vapor</a>, <a href="https://nova.laravel.com" class="underline">Nova</a>, and <a href="https://envoyer.io" class="underline">Envoyer</a> help you take your projects to the next level. Pair them with powerful open source libraries like <a href="https://laravel.com/docs/billing" class="underline">Cashier</a>, <a href="https://laravel.com/docs/dusk" class="underline">Dusk</a>, <a href="https://laravel.com/docs/broadcasting" class="underline">Echo</a>, <a href="https://laravel.com/docs/horizon" class="underline">Horizon</a>, <a href="https://laravel.com/docs/sanctum" class="underline">Sanctum</a>, <a href="https://laravel.com/docs/telescope" class="underline">Telescope</a>, and more.
</div>
</div>
</div>
</div>
</div>
<div class="flex justify-center mt-4 sm:items-center sm:justify-between">
<div class="text-center text-sm text-gray-500 sm:text-left">
<div class="flex items-center">
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor" class="-mt-px w-5 h-5 text-gray-400">
<path d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"></path>
</svg>
<a href="https://laravel.bigcartel.com" class="ml-1 underline">
Shop
</a>
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="ml-4 -mt-px w-5 h-5 text-gray-400">
<path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
<a href="https://github.com/sponsors/taylorotwell" class="ml-1 underline">
Sponsor
</a>
</div>
</div>
<div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,6 +1,7 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController as ControllersHomeController;
/*
|--------------------------------------------------------------------------
@ -16,3 +17,6 @@ use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('fo.welcome');
})->name('home');
Route::get('/', [ControllersHomeController::class, 'index'])->name('home');
Route::view('/charte-de-confidentialite', 'fo.pages.charte')->name('policies');

14
tsconfig.json Normal file
View file

@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "esnext",
"lib": ["es5", "es6", "dom", "dom.iterable"],
"module": "esnext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"typeRoots": ["resources/ts/@types", "node_modules/@types"]
},
"include": ["resources/**/*.js", "resources/**/*.ts", "resources/**/*.vue"],
"exclude": ["node_modules"],
"compileOnSave": false
}

View file

@ -1,50 +1,110 @@
const path = require('path');
const mix = require('laravel-mix');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
require('laravel-mix-polyfill');
require("laravel-mix-polyfill");
require("laravel-mix-clean");
require("laravel-mix-eslint");
require("laravel-mix-stylelint");
const assetDir = "assets";
const polyfill = {
enabled: true,
bugfixes: true,
useBuiltIns: "usage",
targets: "last 3 version, not dead, >0.3%",
};
mix.webpackConfig({
resolve: {
extensions: ["*", ".js", ".vue", ".ts"],
alias: {
'@': path.resolve('resources/assets')
}
"@": path.resolve("resources/assets"),
},
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/],
},
},
{
test: /\.vue$/,
loader: "vue-loader",
options: {
esModule: true,
},
},
],
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
'css/*',
'js/*',
'images/*',
'fonts/*',
'~/assets/*'
]
})
],
});
let assetDir = 'assets';
mix.options({
fileLoaderDirs: {
images: `${assetDir}/images`,
fonts: `${assetDir}/fonts`
fonts: `${assetDir}/fonts`,
},
postCss: [
require('postcss-discard-comments')({
removeAll: true
})
]
require("postcss-discard-comments")({
removeAll: true,
}),
],
});
mix.js("resources/js/back.js", "public/js/preload-back.js")
.js("resources/js/front.js", "public/js/preload-front.js")
.sass("resources/sass/main.scss", "public/css/preload-main.css")
.vue()
.polyfill({
enabled: true,
useBuiltIns: "usage",
targets: { "firefox": "50", "ie": 11 }
mix.clean({
cleanOnceBeforeBuildPatterns: [
"css/*",
"js/*",
"images/*",
"fonts/*",
"assets/*",
],
});
// BACKEND
mix.ts("resources/ts/back.ts", "public/js/back.js", {
transpileOnly: true,
})
.vue({
runtimeOnly: true,
extractStyles: true,
globalStyles: false,
})
.eslint({
fix: true,
extensions: ["js", "ts"],
})
.stylelint({
configFile: ".stylelintrc.json",
files: ["**/*.scss"],
})
.sass("resources/sass/back.scss", "public/css/back.css")
.polyfill(polyfill)
.version();
// FRONTEND
mix.ts("resources/ts/front.ts", "public/js/front.js", {
transpileOnly: true,
})
.vue({
runtimeOnly: true,
extractStyles: true,
globalStyles: false,
})
.eslint({
fix: true,
extensions: ["js", "ts"],
})
.stylelint({
configFile: ".stylelintrc.json",
files: ["**/*.scss"],
})
.sass("resources/sass/front.scss", "public/css/front.css")
.polyfill(polyfill)
.version();
// Copy Blade Images Assets
mix.copyDirectory('resources/assets', 'public/assets');
mix.copyDirectory("resources/assets", "public/assets");