2024-09-06
This commit is contained in:
parent
5045ef25dc
commit
082202007b
58 changed files with 247957 additions and 494 deletions
22
.vscode/settings.json
vendored
22
.vscode/settings.json
vendored
|
|
@ -3,10 +3,30 @@
|
|||
"controle",
|
||||
"controles",
|
||||
"defini",
|
||||
"deplie",
|
||||
"etats",
|
||||
"ETATS",
|
||||
"exts",
|
||||
"gere",
|
||||
"glitchtip",
|
||||
"GLITCHTIP",
|
||||
"leve",
|
||||
"requete",
|
||||
"selecteur",
|
||||
"selecteurs",
|
||||
"Selectionne",
|
||||
"souleve",
|
||||
"tabpanel",
|
||||
"tete"
|
||||
]
|
||||
],
|
||||
"djlint.pythonPath": "/home/gcch/.local/share/pipxu/venvs/8/bin/python",
|
||||
"djlint.useVenv": false,
|
||||
"stylelint.enable": true,
|
||||
"stylelint.packageManager": "pnpm",
|
||||
"twiggy.autoInsertSpaces": true,
|
||||
"twiggy.framework": "ignore",
|
||||
"twiggy.inlayHints.block": true,
|
||||
"twiggy.inlayHints.macro": true,
|
||||
"twiggy.inlayHints.macroArguments": true,
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@
|
|||
"wpackagist-plugin/polylang": "^3.6",
|
||||
"wpackagist-plugin/query-monitor": "^3.16",
|
||||
"mnsami/composer-custom-directory-installer": "^2.0",
|
||||
"htmlburger/carbon-fields": "^3.6"
|
||||
"htmlburger/carbon-fields": "^3.6",
|
||||
"wpackagist-plugin/wp-openapi": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
|
|
|
|||
64
composer.lock
generated
64
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "028568610be8aa5617070402717dc8a1",
|
||||
"content-hash": "d9349cad6f6e130fcb72a1ed8dc15ed6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/installers",
|
||||
|
|
@ -1465,24 +1465,23 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.11.0",
|
||||
"version": "v3.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d"
|
||||
"reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
|
||||
"reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
|
||||
"reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"php": ">=8.0.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php80": "^1.22",
|
||||
"symfony/polyfill-php81": "^1.29"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
@ -1529,7 +1528,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.11.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.12.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -1541,7 +1540,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-08T16:15:16+00:00"
|
||||
"time": "2024-08-29T09:51:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
|
|
@ -1683,15 +1682,15 @@
|
|||
},
|
||||
{
|
||||
"name": "wpackagist-plugin/woocommerce",
|
||||
"version": "9.2.1",
|
||||
"version": "9.2.3",
|
||||
"source": {
|
||||
"type": "svn",
|
||||
"url": "https://plugins.svn.wordpress.org/woocommerce/",
|
||||
"reference": "tags/9.2.1"
|
||||
"reference": "tags/9.2.3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://downloads.wordpress.org/plugin/woocommerce.9.2.1.zip"
|
||||
"url": "https://downloads.wordpress.org/plugin/woocommerce.9.2.3.zip"
|
||||
},
|
||||
"require": {
|
||||
"composer/installers": "^1.0 || ^2.0"
|
||||
|
|
@ -1699,6 +1698,24 @@
|
|||
"type": "wordpress-plugin",
|
||||
"homepage": "https://wordpress.org/plugins/woocommerce/"
|
||||
},
|
||||
{
|
||||
"name": "wpackagist-plugin/wp-openapi",
|
||||
"version": "1.0.12",
|
||||
"source": {
|
||||
"type": "svn",
|
||||
"url": "https://plugins.svn.wordpress.org/wp-openapi/",
|
||||
"reference": "tags/1.0.12"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://downloads.wordpress.org/plugin/wp-openapi.1.0.12.zip"
|
||||
},
|
||||
"require": {
|
||||
"composer/installers": "^1.0 || ^2.0"
|
||||
},
|
||||
"type": "wordpress-plugin",
|
||||
"homepage": "https://wordpress.org/plugins/wp-openapi/"
|
||||
},
|
||||
{
|
||||
"name": "wpackagist-theme/twentytwentyfour",
|
||||
"version": "1.2",
|
||||
|
|
@ -1725,12 +1742,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||
"reference": "8938260885863ec2dd9f2aaf9a79ba14e58a92f6"
|
||||
"reference": "f6547941a3b3a96c1b20b77c6ebf126b195f814e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/8938260885863ec2dd9f2aaf9a79ba14e58a92f6",
|
||||
"reference": "8938260885863ec2dd9f2aaf9a79ba14e58a92f6",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f6547941a3b3a96c1b20b77c6ebf126b195f814e",
|
||||
"reference": "f6547941a3b3a96c1b20b77c6ebf126b195f814e",
|
||||
"shasum": ""
|
||||
},
|
||||
"conflict": {
|
||||
|
|
@ -1866,8 +1883,9 @@
|
|||
"dolibarr/dolibarr": "<19.0.2",
|
||||
"dompdf/dompdf": "<2.0.4",
|
||||
"doublethreedigital/guest-entries": "<3.1.2",
|
||||
"drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2",
|
||||
"drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
||||
"drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2|==11.9999999.9999999.9999999-dev",
|
||||
"drupal/core-recommended": "==11.9999999.9999999.9999999-dev",
|
||||
"drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4|==11.9999999.9999999.9999999-dev",
|
||||
"duncanmcclean/guest-entries": "<3.1.2",
|
||||
"dweeves/magmi": "<=0.7.24",
|
||||
"ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2",
|
||||
|
|
@ -1941,7 +1959,7 @@
|
|||
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
|
||||
"friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
|
||||
"froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3",
|
||||
"froxlor/froxlor": "<2.1.9",
|
||||
"froxlor/froxlor": "<=2.2.0.0-RC3",
|
||||
"frozennode/administrator": "<=5.0.12",
|
||||
"fuel/core": "<1.8.1",
|
||||
"funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3",
|
||||
|
|
@ -1949,7 +1967,7 @@
|
|||
"genix/cms": "<=1.1.11",
|
||||
"getformwork/formwork": "<1.13.1|==2.0.0.0-beta1",
|
||||
"getgrav/grav": "<1.7.46",
|
||||
"getkirby/cms": "<4.1.1",
|
||||
"getkirby/cms": "<=3.6.6.5|>=3.7,<=3.7.5.4|>=3.8,<=3.8.4.3|>=3.9,<=3.9.8.1|>=3.10,<=3.10.1|>=4,<=4.3",
|
||||
"getkirby/kirby": "<=2.5.12",
|
||||
"getkirby/panel": "<2.5.14",
|
||||
"getkirby/starterkit": "<=3.7.0.2",
|
||||
|
|
@ -1996,6 +2014,7 @@
|
|||
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
|
||||
"in2code/ipandlanguageredirect": "<5.1.2",
|
||||
"in2code/lux": "<17.6.1|>=18,<24.0.2",
|
||||
"in2code/powermail": "<7.5|>=8,<8.5|>=9,<10.9|>=11,<12.4",
|
||||
"innologi/typo3-appointments": "<2.0.6",
|
||||
"intelliants/subrion": "<4.2.2",
|
||||
"inter-mediator/inter-mediator": "==5.5",
|
||||
|
|
@ -2178,7 +2197,7 @@
|
|||
"phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5",
|
||||
"phpoffice/common": "<0.2.9",
|
||||
"phpoffice/phpexcel": "<1.8",
|
||||
"phpoffice/phpspreadsheet": "<1.16",
|
||||
"phpoffice/phpspreadsheet": "<1.29.1|>=2,<2.2.1",
|
||||
"phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36",
|
||||
"phpservermon/phpservermon": "<3.6",
|
||||
"phpsysinfo/phpsysinfo": "<3.4.3",
|
||||
|
|
@ -2187,9 +2206,10 @@
|
|||
"phpxmlrpc/extras": "<0.6.1",
|
||||
"phpxmlrpc/phpxmlrpc": "<4.9.2",
|
||||
"pi/pi": "<=2.5",
|
||||
"pimcore/admin-ui-classic-bundle": "<=1.5.1",
|
||||
"pimcore/admin-ui-classic-bundle": "<1.5.4",
|
||||
"pimcore/customer-management-framework-bundle": "<4.0.6",
|
||||
"pimcore/data-hub": "<1.2.4",
|
||||
"pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3",
|
||||
"pimcore/demo": "<10.3",
|
||||
"pimcore/ecommerce-framework-bundle": "<1.0.10",
|
||||
"pimcore/perspective-editor": "<1.5.1",
|
||||
|
|
@ -2534,7 +2554,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-19T21:04:39+00:00"
|
||||
"time": "2024-09-04T15:05:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
|
|
|
|||
10
dprint.json
10
dprint.json
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"extends": "/home/gcch/.dprint.jsonc",
|
||||
"exec": {
|
||||
"cacheKey": 1,
|
||||
"cacheKey": "1",
|
||||
"commands": [
|
||||
{
|
||||
"command": "prettier --ignore-unknown --write --stdin-filepath {{file_path}}",
|
||||
|
|
@ -23,13 +23,13 @@
|
|||
"useTabs": false
|
||||
},
|
||||
"plugins": [
|
||||
"https://plugins.dprint.dev/typescript-0.91.6.wasm",
|
||||
"https://plugins.dprint.dev/typescript-0.91.8.wasm",
|
||||
"https://plugins.dprint.dev/json-0.19.3.wasm",
|
||||
"https://plugins.dprint.dev/markdown-0.17.5.wasm",
|
||||
"https://plugins.dprint.dev/markdown-0.17.8.wasm",
|
||||
"https://plugins.dprint.dev/toml-0.6.2.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/malva-v0.9.1.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/malva-v0.10.1.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.12.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.4.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm",
|
||||
"https://plugins.dprint.dev/exec-0.5.0.json@8d9972eee71fa1590e04873540421f3eda7674d0f1aae3d7c788615e7b7413d0"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
66455
lib/openapi3_1.json
Normal file
66455
lib/openapi3_1.json
Normal file
File diff suppressed because it is too large
Load diff
14486
lib/woocommerce-openapi-3.0.x.yml
Normal file
14486
lib/woocommerce-openapi-3.0.x.yml
Normal file
File diff suppressed because it is too large
Load diff
66455
lib/wp-json-openapi.json
Normal file
66455
lib/wp-json-openapi.json
Normal file
File diff suppressed because it is too large
Load diff
99225
lib/wp-json-schema.json
Normal file
99225
lib/wp-json-schema.json
Normal file
File diff suppressed because it is too large
Load diff
28
package.json
28
package.json
|
|
@ -10,36 +10,40 @@
|
|||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sentry/browser": "^8.28.0",
|
||||
"purify-ts": "^2.1.0",
|
||||
"remeda": "^2.12.0",
|
||||
"valibot": "^0.41.0",
|
||||
"wretch": "^2.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@awmottaz/prettier-plugin-void-html": "^1.6.1",
|
||||
"@biomejs/biome": "1.8.3",
|
||||
"@biomejs/biome": "^1.8.3",
|
||||
"@prettier/plugin-php": "^0.22.2",
|
||||
"@prettier/plugin-xml": "^3.4.1",
|
||||
"@sentry/types": "^8.28.0",
|
||||
"@swc/cli": "^0.4.0",
|
||||
"@swc/core": "^1.7.14",
|
||||
"@zackad/prettier-plugin-twig": "^0.8.0",
|
||||
"browserslist": "^4.23.3",
|
||||
"fdir": "^6.2.0",
|
||||
"fdir": "^6.3.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-pkg": "^0.18.1",
|
||||
"prettier-plugin-sh": "^0.14.0",
|
||||
"sass": "^1.77.8",
|
||||
"stylelint": "^16.8.2",
|
||||
"sass": "^1.78.0",
|
||||
"stylelint": "^16.9.0",
|
||||
"stylelint-config-clean-order": "^6.1.0",
|
||||
"stylelint-config-sass-guidelines": "^12.0.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.8.0",
|
||||
"stylelint-plugin-logical-css": "^1.2.1",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3",
|
||||
"vite-plugin-valibot-env": "^0.6.11",
|
||||
"wp-types": "^4.66.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults",
|
||||
"last 3 years",
|
||||
"not dead"
|
||||
],
|
||||
"dependencies": {
|
||||
"purify-ts": "^2.1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
781
pnpm-lock.yaml
generated
781
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -37,7 +37,7 @@ export default {
|
|||
xmlWhitespaceSensitivity: "strict",
|
||||
},
|
||||
},
|
||||
// Pour package.json
|
||||
// package.json
|
||||
{
|
||||
files: ["package.json"],
|
||||
options: {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,54 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowArbitraryExtensions": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"alwaysStrict": true,
|
||||
"checkJs": true,
|
||||
"downlevelIteration": false,
|
||||
"esModuleInterop": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["DOM", "ES2022"],
|
||||
"module": "NodeNext",
|
||||
"lib": ["DOM", "ES2020", "ES2022"],
|
||||
"module": "ES2022",
|
||||
"moduleDetection": "force",
|
||||
"moduleResolution": "NodeNext",
|
||||
"noEmit": false,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": false,
|
||||
"moduleResolution": "Bundler",
|
||||
"noEmit": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noStrictGenericChecks": false,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"skipLibCheck": false,
|
||||
"strict": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"target": "ES2022"
|
||||
"suppressExcessPropertyErrors": false,
|
||||
"suppressImplicitAnyIndexErrors": false,
|
||||
"target": "ES2022",
|
||||
"types": ["vite/client"],
|
||||
"useDefineForClassFields": true,
|
||||
"useUnknownInCatchVariables": true
|
||||
},
|
||||
"exclude": ["vendor", "web/app/plugins", "web/wp"],
|
||||
"include": ["*.js", "lib", "web/app/themes/haiku-atelier-2024/src"]
|
||||
"exclude": [
|
||||
"vendor",
|
||||
"web/app/plugins",
|
||||
"web/wp"
|
||||
],
|
||||
"include": [
|
||||
"*.js",
|
||||
"lib",
|
||||
"web/app/themes/haiku-atelier-2024/src"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
import { fdir } from "fdir";
|
||||
import { resolve } from "node:path";
|
||||
import * as v from "valibot";
|
||||
import { defineConfig } from "vite";
|
||||
import valibot from "vite-plugin-valibot-env";
|
||||
|
||||
const SLUG_THEME = "haiku-atelier-2024";
|
||||
const SRC_TYPESCRIPT_PATHS = new fdir()
|
||||
.withBasePath()
|
||||
.glob("**/*.ts")
|
||||
.crawl("web/app/themes/haiku-atelier-2024/src/scripts")
|
||||
.filter((path, isDirectory) => !isDirectory && !path.endsWith("lol.ts"))
|
||||
.crawl(`web/app/themes/${SLUG_THEME}/src/scripts`)
|
||||
.withPromise();
|
||||
|
||||
/* Voir le fichier vite.env.d.ts */
|
||||
const SCHEMA_ENVIRONNEMENT = v.object({
|
||||
VITE_URL: v.pipe(v.string(), v.nonEmpty(), v.url(), v.readonly()),
|
||||
VITE_GLITCHTIP_NSD: v.pipe(v.string(), v.url(), v.readonly()),
|
||||
});
|
||||
|
||||
export default defineConfig({
|
||||
base: "",
|
||||
build: {
|
||||
|
|
@ -21,16 +31,21 @@ export default defineConfig({
|
|||
input: await SRC_TYPESCRIPT_PATHS,
|
||||
output: {
|
||||
assetFileNames: "[name][extname]",
|
||||
chunkFileNames: "[name][extname]",
|
||||
entryFileNames: "[name].js",
|
||||
chunkFileNames: "[name].js",
|
||||
compact: true,
|
||||
minifyInternalExports: true,
|
||||
entryFileNames: "[name].js",
|
||||
validate: true,
|
||||
},
|
||||
treeshake: "recommended",
|
||||
treeshake: "smallest",
|
||||
},
|
||||
sourcemap: true,
|
||||
reportCompressedSize: true,
|
||||
target: "es2023",
|
||||
watch: { clearScreen: false },
|
||||
write: true,
|
||||
},
|
||||
plugins: [
|
||||
/* Permet de valider les variables d'environnements définies à partir d'un schéma Valibot */
|
||||
valibot(SCHEMA_ENVIRONNEMENT),
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -557,28 +557,43 @@ ul.avec-puce-cercle a {
|
|||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Boîte flottante avec les informations Produit, le sélecteur de variation et de quantité pour le
|
||||
* Panier.
|
||||
*
|
||||
* 1. Flotte toujours en bas de la page et s'arrête avant les Produits de la même collection.
|
||||
* 2. Conteneur existant pour que le flottement sticky fonctionne ; n'a pas de dimensions.
|
||||
*/
|
||||
.informations-produit {
|
||||
position: sticky;
|
||||
bottom: 1rem;
|
||||
/* Variables */
|
||||
--boite-couleur-fond: rgb(255 255 255 / 90%);
|
||||
--boite-position-basse: 1rem;
|
||||
--boite-longueur: 70ch;
|
||||
--section-marges-internes: 1rem;
|
||||
position: sticky; /* 1 */
|
||||
bottom: var(--boite-position-basse); /* 1 */
|
||||
overflow: visible;
|
||||
width: 0;
|
||||
height: 0;
|
||||
width: 0; /* 2 */
|
||||
height: 0; /* 2 */
|
||||
/* Nom du Produit, sélecteur de variation et prix du Produit */
|
||||
/* Bouton « Ajouter au Panier » */
|
||||
}
|
||||
.informations-produit__conteneur {
|
||||
transform: translate(calc(50vw - 35ch), -100%);
|
||||
transform: translate(calc(50vw - var(--boite-longueur) / 2), -100%);
|
||||
display: grid;
|
||||
width: 70ch;
|
||||
max-width: 70ch;
|
||||
width: var(--boite-longueur);
|
||||
max-width: var(--boite-longueur);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
/**
|
||||
* Définis les apparence et comportement de toutes les sections de la boîte.
|
||||
*/
|
||||
}
|
||||
.informations-produit__conteneur > section {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: var(--section-marges-internes);
|
||||
background: var(--boite-couleur-fond);
|
||||
}
|
||||
.informations-produit__conteneur > section + section {
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
|
|
@ -586,12 +601,13 @@ ul.avec-puce-cercle a {
|
|||
.informations-produit .onglets-details-produit {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-rows: 1fr min-content;
|
||||
grid-template-rows: auto min-content;
|
||||
padding: initial;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > section {
|
||||
overflow-y: auto;
|
||||
grid-column: span 3;
|
||||
padding: 1rem;
|
||||
padding: var(--section-marges-internes);
|
||||
font-weight: 350;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > section[hidden] {
|
||||
|
|
@ -616,24 +632,36 @@ ul.avec-puce-cercle a {
|
|||
.informations-produit .onglets-details-produit > ul li {
|
||||
width: 100%;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li:first-of-type a {
|
||||
border-right-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li:last-of-type a {
|
||||
border-right-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: var(--espace-xs) 0;
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
border-top: 1px solid transparent;
|
||||
border-right: 1px solid var(--couleur-noir);
|
||||
border-left: 1px solid var(--couleur-noir);
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li a:first-of-type {
|
||||
border-left: initial;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li a:last-of-type {
|
||||
border-left: initial;
|
||||
/* Quand l'onglet est sélectionné */
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li a[aria-selected=true] {
|
||||
border-top-color: transparent;
|
||||
}
|
||||
.informations-produit .onglets-details-produit > ul li a:focus, .informations-produit .onglets-details-produit > ul li a:focus-visible {
|
||||
outline-color: transparent;
|
||||
}
|
||||
.informations-produit .onglets-details-produit:has(section:not([hidden])) {
|
||||
grid-template-rows: 12lh min-content;
|
||||
}
|
||||
.informations-produit .onglets-details-produit:has(section:not([hidden])) > ul li a:not([aria-selected=true]) {
|
||||
border-top-color: var(--couleur-noir);
|
||||
}
|
||||
.informations-produit .selecteur-produit {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["../../src/sass/base/polices/_lato.scss","../../src/sass/base/polices/_myriad.scss","../../src/sass/abstracts/_variables.scss","../../src/sass/base/_base.scss","../../src/sass/base/_typographie.scss","../../src/sass/base/elements/_boutons.scss","../../src/sass/base/elements/_images.scss","../../src/sass/base/elements/_liens.scss","../../src/sass/base/elements/_listes.scss","../../src/sass/layouts/_en-tete.scss","../../src/sass/layouts/_menu-categories-produits.scss","../../src/sass/layouts/_colonnes-photos.scss","../../src/sass/layouts/_grille-produits.scss","../../src/sass/layouts/_informations-produit.scss","../../src/sass/layouts/_produits-similaires.scss","../../src/sass/layouts/_pied-de-page.scss"],"names":[],"mappings":";AAAA;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AChGJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AChBJ;AACE;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;AAEA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;;;AClBF;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAIA;EACE;EACA;;;AAGF;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;ACtDF;EACE;EACA;EACA;;;ACHF;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;ACfJ;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;;ACbF;AAAA;AAAA;AAAA;AAAA;AAKA;AACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA,YACE,kHAK4B;EAE9B;AAEA;AAMA;AAAA;AAAA;;AALA;EAEE;;AAMF;AACE;EACA;EACA;AAEA;EACA;EAEA;EACA;AAEA;AAMA;AAKA;;AAVA;EAEE;;AAIF;EACE;;AAIF;EACE;IACE;;;AAMJ;EACE;IACE;;;;AClER;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AACE;EACA;AAEA;EACA;AAEA;EACA;;AAEA;EACE;EACA,qLAEkE;;;AC5BxE;AACE;EACA;EACA;AAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAWA;;AATA;EACE;;AAEA;AAAA;EAEE;;AAKJ;EACE;EACA;EACA;EACA;EACA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AARA;EACE;EACA;EACA;EACA;EACA;;AAYF;AACE;EACA;AAEA;EACA;EACA;EACA;AAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;IACE;;;AAMR;EACE;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;;ACvGR;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AACE;EACA;EACA;AAEA;EACA;EACA;EAEA;EACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAOA;EACE;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAMA;AAAA;AAAA;AAAA;AAAA;;AAJA;EACE;;AAQF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;;AAGF;EACE;IACE;IACA;;;AAKN;EACE;;AAGF;EACE;;;AC/ER;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AACE;EACA;AAEA;EACA;EACA;AAAA;AAAA;AAIA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;;AAMF;EACE;;;AC5CR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AC9EV;EACE;EACA;EACA;EACA;EACA;AAoFA;AAyGA;;AA3LA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAQV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;AAEA;AAMA;AAwCA;AAqBA;;AAlEA;EACE;EACA;;AAIF;EACE;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEI;IACE;IACA;;;AAKN;EAEI;IACE;IACA;;;AAOR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;IACE;;;AAKN;EACE;;AAeJ;EACE;;AAKJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;IACE;;;;AAQZ;EACE;IACE;;EAGF;IACE;;;ACnOJ;EACE;EACA;EACA;EACA,qBACE;EAEF;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AC7FZ;AAAA;AAAA;AAGA;AACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA","file":"main.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../src/sass/base/polices/_lato.scss","../../src/sass/base/polices/_myriad.scss","../../src/sass/abstracts/_variables.scss","../../src/sass/base/_base.scss","../../src/sass/base/_typographie.scss","../../src/sass/base/elements/_boutons.scss","../../src/sass/base/elements/_images.scss","../../src/sass/base/elements/_liens.scss","../../src/sass/base/elements/_listes.scss","../../src/sass/layouts/_en-tete.scss","../../src/sass/layouts/_menu-categories-produits.scss","../../src/sass/layouts/_colonnes-photos.scss","../../src/sass/layouts/_grille-produits.scss","../../src/sass/layouts/_informations-produit.scss","../../src/sass/layouts/_produits-similaires.scss","../../src/sass/layouts/_pied-de-page.scss"],"names":[],"mappings":";AAAA;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,KACE;;AChGJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AChBJ;AACE;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;AAEA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;;;AClBF;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAIA;EACE;EACA;;;AAGF;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;ACtDF;EACE;EACA;EACA;;;ACHF;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;ACfJ;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;;ACbF;AAAA;AAAA;AAAA;AAAA;AAKA;AACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA,YACE,kHAK4B;EAE9B;AAEA;AAMA;AAAA;AAAA;;AALA;EAEE;;AAMF;AACE;EACA;EACA;AAEA;EACA;EAEA;EACA;AAEA;AAMA;AAKA;;AAVA;EAEE;;AAIF;EACE;;AAIF;EACE;IACE;;;AAMJ;EACE;IACE;;;;AClER;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AACE;EACA;AAEA;EACA;AAEA;EACA;;AAEA;EACE;EACA,qLAEkE;;;AC5BxE;AACE;EACA;EACA;AAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAWA;;AATA;EACE;;AAEA;AAAA;EAEE;;AAKJ;EACE;EACA;EACA;EACA;EACA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AARA;EACE;EACA;EACA;EACA;EACA;;AAYF;AACE;EACA;AAEA;EACA;EACA;EACA;AAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;IACE;;;AAMR;EACE;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;;ACvGR;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AACE;EACA;EACA;AAEA;EACA;EACA;EAEA;EACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAOA;EACE;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAMA;AAAA;AAAA;AAAA;AAAA;;AAJA;EACE;;AAQF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;;AAGF;EACE;IACE;IACA;;;AAKN;EACE;;AAGF;EACE;;;AC/ER;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AACE;EACA;AAEA;EACA;EACA;AAAA;AAAA;AAIA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;;AAMF;EACE;;;AC5CR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AC9EV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AACE;EAEA;EAGA;EACA;EAGA;EAEA;EACA;EACA;EACA;EACA;AAuGA;AAyGA;;AA9MA;EACE;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;;AACA;EACE;;AAGF;EACE;;AAMR;EACE;;AAEA;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;AAEA;AAMA;AAwCA;AAqBA;;AAlEA;EACE;EACA;;AAIF;EACE;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEI;IACE;IACA;;;AAKN;EAEI;IACE;IACA;;;AAOR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;IACE;;;AAKN;EACE;;AAeJ;EACE;;AAKJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGE;EACE;IACE;;;;AAQZ;EACE;IACE;;EAGF;IACE;;;ACxQJ;EACE;EACA;EACA;EACA,qBACE;EAEF;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AC7FZ;AAAA;AAAA;AAGA;AACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA","file":"main.css"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,17 +1,97 @@
|
|||
{
|
||||
"_Either.js": {
|
||||
"file": "Either.js",
|
||||
"name": "Either"
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/gaffe.ts": {
|
||||
"file": "gaffe.js",
|
||||
"name": "gaffe",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/gaffe.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/api.ts": {
|
||||
"file": "api.js",
|
||||
"name": "api",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/api.ts",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/constantes.ts",
|
||||
"_Either.js"
|
||||
]
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/constantes.ts": {
|
||||
"file": "constantes.js",
|
||||
"name": "constantes",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/constantes.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts": {
|
||||
"file": "dom.js",
|
||||
"name": "dom",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
|
||||
"_Either.js"
|
||||
]
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts": {
|
||||
"file": "erreurs.js",
|
||||
"name": "erreurs",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/gestion-panier.ts": {
|
||||
"file": "gestion-panier.js",
|
||||
"name": "gestion-panier",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/gestion-panier.ts",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/constantes.ts",
|
||||
"_Either.js"
|
||||
]
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts": {
|
||||
"file": "utils.js",
|
||||
"name": "utils",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts",
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
|
||||
"_Either.js"
|
||||
]
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts": {
|
||||
"file": "scripts-page-produit.js",
|
||||
"name": "scripts-page-produit",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/constantes.ts",
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/types/cart-add-item.ts",
|
||||
"_Either.js",
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts"
|
||||
]
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/types/cart-add-item.ts": {
|
||||
"file": "cart-add-item.js",
|
||||
"name": "cart-add-item",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/types/cart-add-item.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/types/cart.ts": {
|
||||
"file": "cart.js",
|
||||
"name": "cart",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/types/cart.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts": {
|
||||
"file": "vite.env.d.js",
|
||||
"name": "vite.env.d",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts",
|
||||
"isEntry": true
|
||||
}
|
||||
}
|
||||
2
web/app/themes/haiku-atelier-2024/assets/js/Either.js
Normal file
2
web/app/themes/haiku-atelier-2024/assets/js/Either.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
web/app/themes/haiku-atelier-2024/assets/js/api.js
Normal file
3
web/app/themes/haiku-atelier-2024/assets/js/api.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import{d as S}from"./constantes.js";import{r as F}from"./Either.js";const H="application/json",w="Content-Type",_=Symbol(),P=Symbol();function O(t={}){var e;return(e=Object.entries(t).find(([o])=>o.toLowerCase()===w.toLowerCase()))===null||e===void 0?void 0:e[1]}function R(t){return/^application\/.*json.*/.test(t)}const f=function(t,e,o=!1){return Object.entries(e).reduce((n,[i,l])=>{const h=t[i];return Array.isArray(h)&&Array.isArray(l)?n[i]=o?[...h,...l]:l:typeof h=="object"&&typeof l=="object"?n[i]=f(h,l,o):n[i]=l,n},{...t})},y={options:{},errorType:"text",polyfills:{},polyfill(t,e=!0,o=!1,...n){const i=this.polyfills[t]||(typeof self<"u"?self[t]:null)||(typeof global<"u"?global[t]:null);if(e&&!i)throw new Error(t+" is not defined");return o&&i?new i(...n):i}};function L(t,e=!1){y.options=e?t:f(y.options,t)}function N(t,e=!1){y.polyfills=e?t:f(y.polyfills,t)}function I(t){y.errorType=t}const J=t=>e=>t.reduceRight((o,n)=>n(o),e)||e;class x extends Error{}const U=t=>{const e=Object.create(null);t=t._addons.reduce((r,s)=>s.beforeRequest&&s.beforeRequest(r,t._options,e)||r,t);const{_url:o,_options:n,_config:i,_catchers:l,_resolvers:h,_middlewares:g,_addons:m}=t,p=new Map(l),D=f(i.options,n);let T=o;const j=J(g)((r,s)=>(T=r,i.polyfill("fetch")(r,s)))(o,D),b=new Error,v=j.catch(r=>{throw{[_]:r}}).then(r=>{if(!r.ok){const s=new x;if(s.cause=b,s.stack=s.stack+`
|
||||
CAUSE: `+b.stack,s.response=r,s.url=T,r.type==="opaque")throw s;return r.text().then(a=>{var c;if(s.message=a,i.errorType==="json"||((c=r.headers.get("Content-Type"))===null||c===void 0?void 0:c.split(";")[0])==="application/json")try{s.json=JSON.parse(a)}catch{}throw s.text=a,s.status=r.status,s})}return r}),A=r=>r.catch(s=>{const a=s.hasOwnProperty(_),c=a?s[_]:s,E=c?.status&&p.get(c.status)||p.get(c?.name)||a&&p.has(_)&&p.get(_);if(E)return E(c,t);const C=p.get(P);if(C)return C(c,t);throw c}),d=r=>s=>A(r?v.then(a=>a&&a[r]()).then(a=>s?s(a):a):v.then(a=>s?s(a):a)),M={_wretchReq:t,_fetchReq:j,_sharedState:e,res:d(null),json:d("json"),blob:d("blob"),formData:d("formData"),arrayBuffer:d("arrayBuffer"),text:d("text"),error(r,s){return p.set(r,s),this},badRequest(r){return this.error(400,r)},unauthorized(r){return this.error(401,r)},forbidden(r){return this.error(403,r)},notFound(r){return this.error(404,r)},timeout(r){return this.error(408,r)},internalError(r){return this.error(500,r)},fetchError(r){return this.error(_,r)}},q=m.reduce((r,s)=>({...r,...typeof s.resolver=="function"?s.resolver(r):s.resolver}),M);return h.reduce((r,s)=>s(r,t),q)},k={_url:"",_options:{},_config:y,_catchers:new Map,_resolvers:[],_deferred:[],_middlewares:[],_addons:[],addon(t){return{...this,_addons:[...this._addons,t],...t.wretch}},errorType(t){return{...this,_config:{...this._config,errorType:t}}},polyfills(t,e=!1){return{...this,_config:{...this._config,polyfills:e?t:f(this._config.polyfills,t)}}},url(t,e=!1){if(e)return{...this,_url:t};const o=this._url.split("?");return{...this,_url:o.length>1?o[0]+t+"?"+o[1]:this._url+t}},options(t,e=!1){return{...this,_options:e?t:f(this._options,t)}},headers(t){const e=t?Array.isArray(t)?Object.fromEntries(t):"entries"in t?Object.fromEntries(t.entries()):t:{};return{...this,_options:f(this._options,{headers:e})}},accept(t){return this.headers({Accept:t})},content(t){return this.headers({[w]:t})},auth(t){return this.headers({Authorization:t})},catcher(t,e){const o=new Map(this._catchers);return o.set(t,e),{...this,_catchers:o}},catcherFallback(t){return this.catcher(P,t)},resolve(t,e=!1){return{...this,_resolvers:e?[t]:[...this._resolvers,t]}},defer(t,e=!1){return{...this,_deferred:e?[t]:[...this._deferred,t]}},middlewares(t,e=!1){return{...this,_middlewares:e?t:[...this._middlewares,...t]}},fetch(t=this._options.method,e="",o=null){let n=this.url(e).options({method:t});const i=O(n._options.headers),l=this._config.polyfill("FormData",!1),h=typeof o=="object"&&!(l&&o instanceof l)&&(!n._options.headers||!i||R(i));return n=o?h?n.json(o,i):n.body(o):n,U(n._deferred.reduce((g,m)=>m(g,g._url,g._options),n))},get(t=""){return this.fetch("GET",t)},delete(t=""){return this.fetch("DELETE",t)},put(t,e=""){return this.fetch("PUT",e,t)},post(t,e=""){return this.fetch("POST",e,t)},patch(t,e=""){return this.fetch("PATCH",e,t)},head(t=""){return this.fetch("HEAD",t)},opts(t=""){return this.fetch("OPTIONS",t)},body(t){return{...this,_options:{...this._options,body:t}}},json(t,e){const o=O(this._options.headers);return this.content(e||R(o)&&o||H).body(JSON.stringify(t))}};function u(t="",e={}){return{...k,_url:t,_options:e}}u.default=u;u.options=L;u.errorType=I;u.polyfills=N;u.WretchError=x;fetch(S,{credentials:"same-origin",headers:{"Content-Type":"application/json"},method:"GET",mode:"same-origin",signal:AbortSignal.timeout(5e3)}).then(F);u(S).content("application/json").options({credentials:"same-origin",mode:"same-origin",signal:AbortSignal.timeout(5e3)}).get().json().catch();
|
||||
//# sourceMappingURL=api.js.map
|
||||
1
web/app/themes/haiku-atelier-2024/assets/js/api.js.map
Normal file
1
web/app/themes/haiku-atelier-2024/assets/js/api.js.map
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,2 @@
|
|||
var y;function g(e){return{lang:e?.lang??y?.lang,message:e?.message,abortEarly:e?.abortEarly??y?.abortEarly,abortPipeEarly:e?.abortPipeEarly??y?.abortPipeEarly}}var E;function d(e){return E?.get(e)}var k;function _(e){return k?.get(e)}var A;function I(e,s){return A?.get(e)?.get(s)}function S(e){const s=typeof e;return s==="string"?`"${e}"`:s==="number"||s==="bigint"||s==="boolean"?`${e}`:s==="object"||s==="function"?(e&&Object.getPrototypeOf(e)?.constructor?.name)??"null":s}function c(e,s,r,n,t){const i=r.value,o=e.expects??null,u=S(i),l={kind:e.kind,type:e.type,input:i,expected:o,received:u,message:`Invalid ${s}: ${o?`Expected ${o} but r`:"R"}eceived ${u}`,requirement:e.requirement,path:t?.path,issues:t?.issues,lang:n.lang,abortEarly:n.abortEarly,abortPipeEarly:n.abortPipeEarly},a=e.kind==="schema",f=e.message??I(e.reference,l.lang)??(a?_(l.lang):null)??n.message??d(l.lang);f&&(l.message=typeof f=="function"?f(l):f),a&&(r.typed=!1),r.issues?r.issues.push(l):r.issues=[l]}var j=class extends Error{issues;constructor(e){super(e[0].message),this.name="ValiError",this.issues=e}};function C(e,s,r){return typeof e.default=="function"?e.default(s,r):e.default}function b(e,s){return{kind:"schema",type:"array",reference:b,expects:"Array",async:!1,item:e,message:s,_run(r,n){const t=r.value;if(Array.isArray(t)){r.typed=!0,r.value=[];for(let i=0;i<t.length;i++){const o=t[i],u=this.item._run({typed:!1,value:o},n);if(u.issues){const l={type:"array",origin:"value",input:t,key:i,value:o};for(const a of u.issues)a.path?a.path.unshift(l):a.path=[l],r.issues?.push(a);if(r.issues||(r.issues=u.issues),n.abortEarly){r.typed=!1;break}}u.typed||(r.typed=!1),r.value.push(u.value)}}else c(this,"type",r,n);return r}}}function v(e){return{kind:"schema",type:"number",reference:v,expects:"number",async:!1,message:e,_run(s,r){return typeof s.value=="number"&&!isNaN(s.value)?s.typed=!0:c(this,"type",s,r),s}}}function m(e,s){return{kind:"schema",type:"object",reference:m,expects:"Object",async:!1,entries:e,message:s,_run(r,n){const t=r.value;if(t&&typeof t=="object"){r.typed=!0,r.value={};for(const i in this.entries){const o=t[i],u=this.entries[i]._run({typed:!1,value:o},n);if(u.issues){const l={type:"object",origin:"value",input:t,key:i,value:o};for(const a of u.issues)a.path?a.path.unshift(l):a.path=[l],r.issues?.push(a);if(r.issues||(r.issues=u.issues),n.abortEarly){r.typed=!1;break}}u.typed||(r.typed=!1),(u.value!==void 0||i in t)&&(r.value[i]=u.value)}}else c(this,"type",r,n);return r}}}function p(e,...s){const r={kind:"schema",type:"optional",reference:p,expects:`(${e.expects} | undefined)`,async:!1,wrapped:e,_run(n,t){return n.value===void 0&&("default"in this&&(n.value=C(this,n,t)),n.value===void 0)?(n.typed=!0,n):this.wrapped._run(n,t)}};return 0 in s&&(r.default=s[0]),r}function h(e){return{kind:"schema",type:"string",reference:h,expects:"string",async:!1,message:e,_run(s,r){return typeof s.value=="string"?s.typed=!0:c(this,"type",s,r),s}}}function $(e,s,r){const n=e._run({typed:!1,value:s},g(r));if(n.issues)throw new j(n.issues);return n.value}const P=m({attribute:h(),value:h()}),x=m({id:p(v()),quantity:p(v()),variation:p(b(P))}),W=e=>$(x,e);export{W};
|
||||
//# sourceMappingURL=cart-add-item.js.map
|
||||
File diff suppressed because one or more lines are too long
1
web/app/themes/haiku-atelier-2024/assets/js/cart.js
Normal file
1
web/app/themes/haiku-atelier-2024/assets/js/cart.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
//# sourceMappingURL=cart.js.map
|
||||
1
web/app/themes/haiku-atelier-2024/assets/js/cart.js.map
Normal file
1
web/app/themes/haiku-atelier-2024/assets/js/cart.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"cart.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const t="aria-selected",T="hidden",a=".compte-panier a[rel='cart']",s="#selecteur-variation",_="#bouton-ajout-panier",E="wp-json",c=`/${E}/wc/store/cart`,o=`/${E}/wc/store/cart/add-item`;export{t as A,o as R,a as S,s as a,_ as b,T as c,c as d};
|
||||
//# sourceMappingURL=constantes.js.map
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"constantes.js","sources":["../../src/scripts/lib/constantes.ts"],"sourcesContent":["export const ATTRIBUT_ARIA_SELECTED = \"aria-selected\";\nexport const ATTRIBUT_ARIA_HIDDEN = \"aria-hidden\";\nexport const ATTRIBUT_HIDDEN = \"hidden\";\n\nexport const SELECTEUR_BOUTON_PANIER = \".compte-panier a[rel='cart']\";\nexport const SELECTEUR_SELECTEUR_QUANTITE = \"#selecteur-variation\";\nexport const SELECTEUR_BOUTON_AJOUT_PANIER = \"#bouton-ajout-panier\";\n\nexport const CHEMIN_API_REST = \"wp-json\";\nexport const ROUTE_API_PANIER = `/${CHEMIN_API_REST}/wc/store/cart`;\nexport const ROUTE_API_AJOUTE_ARTICLE_PANIER = `/${CHEMIN_API_REST}/wc/store/cart/add-item`;\n"],"names":["ATTRIBUT_ARIA_SELECTED","ATTRIBUT_HIDDEN","SELECTEUR_BOUTON_PANIER","SELECTEUR_SELECTEUR_QUANTITE","SELECTEUR_BOUTON_AJOUT_PANIER","CHEMIN_API_REST","ROUTE_API_PANIER","ROUTE_API_AJOUTE_ARTICLE_PANIER"],"mappings":"AAAO,MAAMA,EAAyB,gBAEzBC,EAAkB,SAElBC,EAA0B,+BAC1BC,EAA+B,uBAC/BC,EAAgC,uBAEhCC,EAAkB,UAClBC,EAAmB,IAAID,CAAe,iBACtCE,EAAkC,IAAIF,CAAe"}
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
const l=t=>r=>{const e=Array.from(t.querySelectorAll(r));if(!e||e.length===0)throw new Error(`La requête "${r}" n'a débouché sur aucun Élément.`);return e};export{l as s};
|
||||
import{c as u,E as c,a as h}from"./erreurs.js";import{E as p,r as y,l as E}from"./Either.js";var x={done:!1,hasNext:!1};function S(e,...r){let t=e,l=r.map(i=>"lazy"in i?A(i):void 0),n=0;for(;n<r.length;){if(l[n]===void 0||!d(t)){let a=r[n];t=a(t),n+=1;continue}let i=[];for(let a=n;a<r.length;a++){let o=l[a];if(o===void 0||(i.push(o),o.isSingle))break}let s=[];for(let a of t)if(g(a,s,i))break;let{isSingle:f}=i.at(-1);t=f?s[0]:s,n+=i.length}return t}function g(e,r,t){if(t.length===0)return r.push(e),!1;let l=e,n=x,i=!1;for(let[s,f]of t.entries()){let{index:a,items:o}=f;if(o.push(l),n=f(l,a,o),f.index+=1,n.hasNext){if(n.hasMany??!1){for(let m of n.next)if(g(m,r,t.slice(s+1)))return!0;return i}l=n.next}if(!n.hasNext)break;n.done&&(i=!0)}return n.hasNext&&r.push(l),i}function A(e){let{lazy:r,lazyArgs:t}=e,l=r(...t);return Object.assign(l,{isSingle:r.single??!1,index:0,items:[]})}function d(e){return typeof e=="string"||typeof e=="object"&&e!==null&&Symbol.iterator in e}function N(e){return e!==null}function b(e){return e===void 0?!0:typeof e=="string"||Array.isArray(e)?e.length===0:Object.keys(e).length===0}const _=e=>r=>p.encase(()=>e.querySelector(r)).mapLeft(t=>u(c(r))).chain(t=>N(t)?y(t):E(u(h(r)))),k=e=>r=>p.encase(()=>S(e.querySelectorAll(r),Array.from)).mapLeft(t=>u(c(r))).chain(t=>b(t)?E(u(h(r))):y(t));export{k as a,_ as r};
|
||||
//# sourceMappingURL=dom.js.map
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
2
web/app/themes/haiku-atelier-2024/assets/js/erreurs.js
Normal file
2
web/app/themes/haiku-atelier-2024/assets/js/erreurs.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
const r=e=>`Le selecteur "${e}" est invalide`,E=e=>`La requête "${e}" n'a retourné aucun Élément.`,t=e=>new SyntaxError(e),n=e=>{throw e};export{r as E,E as a,t as c,n as l};
|
||||
//# sourceMappingURL=erreurs.js.map
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"erreurs.js","sources":["../../src/scripts/lib/erreurs.ts"],"sourcesContent":["/**\n * Fonctions pour la création d'Erreurs.\n */\n\n/* Messages d'erreur */\nexport const ERREUR_SYNTAXE_INVALIDE: (selecteur: string) => string = (selecteur) =>\n `Le selecteur \"${selecteur}\" est invalide`;\nexport const ERREUR_SELECTEUR_INEXISTANT: (selecteur: string) => string = (selecteur) =>\n `La requête \"${selecteur}\" n'a retourné aucun Élément.`;\n\n/* Création d'erreurs */\nexport const creeSyntaxError: (message: string) => SyntaxError = (message) => new SyntaxError(message);\n\nexport const leveErreur: (erreur: Error) => never = (erreur) => {\n throw erreur;\n};\n"],"names":["ERREUR_SYNTAXE_INVALIDE","selecteur","ERREUR_SELECTEUR_INEXISTANT","creeSyntaxError","message","leveErreur","erreur"],"mappings":"AAKO,MAAMA,EAA0DC,GACrE,iBAAiBA,CAAS,iBACfC,EAA8DD,GACzE,eAAeA,CAAS,gCAGbE,EAAqDC,GAAY,IAAI,YAAYA,CAAO,EAExFC,EAAwCC,GAAW,CACxD,MAAAA,CACR"}
|
||||
9
web/app/themes/haiku-atelier-2024/assets/js/gaffe.js
Normal file
9
web/app/themes/haiku-atelier-2024/assets/js/gaffe.js
Normal file
File diff suppressed because one or more lines are too long
1
web/app/themes/haiku-atelier-2024/assets/js/gaffe.js.map
Normal file
1
web/app/themes/haiku-atelier-2024/assets/js/gaffe.js.map
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,2 @@
|
|||
import{d as g}from"./constantes.js";import{E as h,r as o,l as f,M,n as u,j as c}from"./Either.js";var l;const y={liftEither(i){if(i.isRight())return Promise.resolve(i.extract());throw i.extract()},fromPromise(i){return i.then(y.liftEither)},throwE(i){throw i}};class m{constructor(t){this.runPromise=t,this[l]="EitherAsync",this["fantasy-land/chain"]=this.chain,this["fantasy-land/alt"]=this.alt,this.then=(r,e)=>this.run().then(r,e)}leftOrDefault(t){return this.run().then(r=>r.leftOrDefault(t))}orDefault(t){return this.run().then(r=>r.orDefault(t))}join(){return n(async t=>{const r=await this;if(r.isRight()){const e=await r.extract();return t.liftEither(e)}return t.liftEither(r)})}ap(t){return n(async r=>{const e=await t;if(e.isRight()){const a=await this.run();return a.isRight()?e.extract()(a.extract()):r.liftEither(a)}return r.liftEither(e)})}alt(t){return n(async r=>{const e=await this.run();if(e.isRight())return e.extract();{const a=await t;return r.liftEither(a)}})}extend(t){return n(async r=>{const e=await this.run();if(e.isRight()){const a=n.liftEither(e);return r.liftEither(o(t(a)))}return r.liftEither(e)})}async run(){try{return o(await this.runPromise(y))}catch(t){return f(t)}}bimap(t,r){return n(async e=>{const a=await this.run();try{return await e.liftEither(a.bimap(t,r))}catch(P){throw await P}})}map(t){return n(r=>this.runPromise(r).then(t))}mapLeft(t){return n(async r=>{try{return await this.runPromise(r)}catch(e){throw await t(e)}})}chain(t){return n(async r=>{const e=await this.runPromise(r);return r.fromPromise(t(e))})}chainLeft(t){return n(async r=>{try{return await this.runPromise(r)}catch(e){return r.fromPromise(t(e))}})}toMaybeAsync(){return s(async({liftMaybe:t})=>{const r=await this.run();return t(r.toMaybe())})}swap(){return n(async t=>{const r=await this.run();return r.isRight()&&t.throwE(r.extract()),t.liftEither(o(r.extract()))})}ifLeft(t){return n(async r=>{const e=await this.run();return e.ifLeft(t),r.liftEither(e)})}ifRight(t){return n(async r=>{const e=await this.run();return e.ifRight(t),r.liftEither(e)})}void(){return this.map(t=>{})}caseOf(t){return this.run().then(r=>r.caseOf(t))}finally(t){return n(({fromPromise:r})=>r(this.run().finally(t)))}}l=Symbol.toStringTag;const n=Object.assign(i=>new m(i),{fromPromise:i=>n(({fromPromise:t})=>t(i())),liftEither:i=>n(({liftEither:t})=>t(i)),lefts:i=>Promise.all(i.map(t=>t.run())).then(h.lefts),rights:i=>Promise.all(i.map(t=>t.run())).then(h.rights),sequence:i=>n(async t=>{let r=[];for await(const e of i){if(e.isLeft())return t.liftEither(e);r.push(e.extract())}return t.liftEither(o(r))}),all:i=>n.fromPromise(async()=>Promise.all(i).then(h.sequence))});m.prototype.constructor=n;var w;const b={liftMaybe(i){if(i.isJust())return Promise.resolve(i.extract());throw u},fromPromise(i){return i.then(b.liftMaybe)}};class E{constructor(t){this.runPromise=t,this[w]="MaybeAsync",this["fantasy-land/chain"]=this.chain,this["fantasy-land/filter"]=this.filter,this["fantasy-land/alt"]=this.alt}orDefault(t){return this.run().then(r=>r.orDefault(t))}join(){return s(async t=>{const r=await this.run();if(r.isJust()){const e=await r.extract();return t.liftMaybe(e)}return t.liftMaybe(u)})}ap(t){return s(async r=>{const e=await t;if(e.isJust()){const a=await this.run();return a.isJust()?e.extract()(a.extract()):r.liftMaybe(u)}return r.liftMaybe(u)})}alt(t){return s(async r=>{const e=await this.run();if(e.isJust())return e.extract();{const a=await t;return r.liftMaybe(a)}})}extend(t){return s(async r=>{const e=await this.run();if(e.isJust()){const a=s.liftMaybe(e);return r.liftMaybe(c(t(a)))}return r.liftMaybe(u)})}filter(t){return s(async r=>{const e=await this.run();return r.liftMaybe(e.filter(t))})}async run(){try{return c(await this.runPromise(b))}catch{return u}}map(t){return s(r=>this.runPromise(r).then(t))}chain(t){return s(async r=>{const e=await this.runPromise(r);return r.fromPromise(t(e))})}toEitherAsync(t){return n(async({liftEither:r})=>{const e=await this.run();return r(e.toEither(t))})}ifJust(t){return s(async r=>{const e=await this.run();return e.ifJust(t),r.liftMaybe(e)})}ifNothing(t){return s(async r=>{const e=await this.run();return e.ifNothing(t),r.liftMaybe(e)})}void(){return this.map(t=>{})}caseOf(t){return this.run().then(r=>r.caseOf(t))}finally(t){return s(({fromPromise:r})=>r(this.run().finally(t)))}then(t,r){return this.run().then(t,r)}}w=Symbol.toStringTag;const s=Object.assign(i=>new E(i),{catMaybes:i=>Promise.all(i).then(M.catMaybes),fromPromise:i=>s(({fromPromise:t})=>t(i())),liftMaybe:i=>s(({liftMaybe:t})=>t(i))});E.prototype.constructor=s;const p=_etats,d=()=>fetch(g,{credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json","X-WC-Store-API-Nonce":p.nonce},method:"GET",mode:"same-origin",signal:AbortSignal.timeout(5e3)}).then(o).catch(f);n.fromPromise(d).map(i=>i.json()).ifLeft(i=>console.error(i));
|
||||
//# sourceMappingURL=gestion-panier.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,2 +1,2 @@
|
|||
import{s as a}from"./dom.js";const c=o=>{o.forEach(t=>{t[0].setAttribute("aria-selected","false"),t[1].setAttribute("hidden","true")})},d=()=>{const o=a(document)("a[role='tab']"),t=a(document)("section[role='tabpanel']"),r=new Map;o.forEach((e,s)=>{const n=e.getAttribute("id"),i=t[s];if(!n)throw new Error("Le lien ne dispose pas d'ID !");if(!i)throw new Error("Le lien ne dispose pas de section correspondante !");r.set(n,[e,i])}),Array.from(r.values()).forEach(e=>{e[0].addEventListener("click",s=>{s.preventDefault();const n=e[0].getAttribute("aria-selected")==="true";c(Array.from(r.values())),!n&&(e[0].setAttribute("aria-selected","true"),e[1].removeAttribute("hidden"))})}),console.debug(r)};document.addEventListener("DOMContentLoaded",()=>{d()});
|
||||
import{S as p,a as T,b as g,A as E,c as m,R as L}from"./constantes.js";import{l as a}from"./erreurs.js";import{r as d,a as f}from"./utils.js";import{W as O}from"./cart-add-item.js";import{E as h}from"./Either.js";import"./dom.js";const c=n=>n,A=_etats,R=n=>{n.forEach(t=>{t[0].setAttribute(E,"false"),t[1].setAttribute(m,"true")})},I=d(p),_=()=>{const n=f("a[role='tab']").caseOf({Left:a,Right:c}),t=f("section[role='tabpanel']").caseOf({Left:a,Right:c}),o=d(T).caseOf({Left:a,Right:c}),r=d(g).caseOf({Left:a,Right:c}),s=new Map;n.forEach((e,u)=>{const i=e.getAttribute("id"),l=t[u];if(!i)throw new Error("Le lien ne dispose pas d'ID !");if(!l)throw new Error("Le lien ne dispose pas de section correspondante !");s.set(i,[e,l])}),Array.from(s.values()).forEach(e=>{e[0].addEventListener("click",u=>{u.preventDefault();const i=e[0].getAttribute(E)==="true";R(Array.from(s.values())),!i&&(e[0].setAttribute(E,"true"),e[1].removeAttribute(m))})}),o.addEventListener("change",e=>{console.debug(o.value,e)}),r.addEventListener("click",e=>{e.preventDefault(),b()}),console.debug(s)},b=()=>{const n={quantity:1,id:A.idProduit};h.encase(()=>O(n)).ifLeft(t=>console.error(t)).map(t=>{fetch(L,{body:JSON.stringify(t),credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json","X-WC-Store-API-Nonce":A.nonce},method:"POST",mode:"same-origin",signal:AbortSignal.timeout(5e3)}).then(o=>o.json()).then(o=>{I.caseOf({Left:r=>console.error("Le bouton du Panier n'existe pas !",r),Right:r=>{console.debug(r),r.textContent=`cart ${o.items.length}`}})}).catch(o=>console.error(o))})};document.addEventListener("DOMContentLoaded",()=>{_()});
|
||||
//# sourceMappingURL=scripts-page-produit.js.map
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
2
web/app/themes/haiku-atelier-2024/assets/js/utils.js
Normal file
2
web/app/themes/haiku-atelier-2024/assets/js/utils.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import{r as e,a as r}from"./dom.js";import"./erreurs.js";import"./Either.js";const o=r(document),n=e(document);export{o as a,n as r};
|
||||
//# sourceMappingURL=utils.js.map
|
||||
1
web/app/themes/haiku-atelier-2024/assets/js/utils.js.map
Normal file
1
web/app/themes/haiku-atelier-2024/assets/js/utils.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"utils.js","sources":["../../src/scripts/lib/utils.ts"],"sourcesContent":["import type { Either } from \"purify-ts\";\nimport { recupereElementAvecSelecteur, recupereElementsAvecSelecteur } from \"./dom\";\n\nexport const recupereElementsDocument: (selecteur: string) => Either<SyntaxError, Element[]> =\n recupereElementsAvecSelecteur(document);\n\nexport const recupereElementDocument: <E extends Element = Element>(selecteur: string) => Either<SyntaxError, E> =\n recupereElementAvecSelecteur(document);\n"],"names":["recupereElementAvecSelecteur","recupereElementsAvecSelecteur","recupereElementsDocument","recupereElementDocument"],"mappings":"AAGa,OAAA,KAAAA,EAAA,KAAAC,MAAA,WAAA,MAAA,eAAA,MAAA,cAAA,MAAAC,EACXD,EAA8B,QAAQ,EAE3BE,EACXH,EAA6B,QAAQ"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
//# sourceMappingURL=vite.env.d.js.map
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"vite.env.d.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
|
|
@ -19,23 +19,21 @@ $produits_collection = array_map(
|
|||
"recupere_informations_produit_page_produit",
|
||||
recupere_produits_meme_collection($produit["collection"])($produit["id"]),
|
||||
);
|
||||
$nonce = wp_create_nonce("wc_store_api");
|
||||
|
||||
$contexte["produit"] = $produit;
|
||||
$contexte["produits_collection"] = $produits_collection;
|
||||
|
||||
/* echo "<pre>";
|
||||
print_r($produit);
|
||||
echo "</pre>"; */
|
||||
$contexte["nonce"] = $nonce;
|
||||
|
||||
/**
|
||||
* Charge les Scripts nécessaires pour la page Produit.
|
||||
*/
|
||||
function charge_scripts_page_produit(): void {
|
||||
wp_enqueue_script_module(
|
||||
$id = "haiku-atelier-2024-scripts-page-produit",
|
||||
$src = get_template_directory_uri() . "/assets/js/scripts-page-produit.js",
|
||||
$deps = [],
|
||||
$ver = filemtime(get_template_directory() . "/assets/js/scripts-page-produit.js"),
|
||||
id: "haiku-atelier-2024-scripts-page-produit",
|
||||
src: get_template_directory_uri() . "/assets/js/scripts-page-produit.js",
|
||||
deps: [],
|
||||
version: filemtime(get_template_directory() . "/assets/js/scripts-page-produit.js"),
|
||||
);
|
||||
}
|
||||
add_action("wp_enqueue_scripts", "charge_scripts_page_produit");
|
||||
|
|
|
|||
|
|
@ -1,25 +1,46 @@
|
|||
// Styles pour la boîte flottante des Informations sur le Produit
|
||||
|
||||
/**
|
||||
* Boîte flottante avec les informations Produit, le sélecteur de variation et de quantité pour le
|
||||
* Panier.
|
||||
*
|
||||
* 1. Flotte toujours en bas de la page et s'arrête avant les Produits de la même collection.
|
||||
* 2. Conteneur existant pour que le flottement sticky fonctionne ; n'a pas de dimensions.
|
||||
*/
|
||||
.informations-produit {
|
||||
position: sticky;
|
||||
bottom: 1rem;
|
||||
/* Variables */
|
||||
// Couleurs
|
||||
--boite-couleur-fond: rgb(255 255 255 / 90%);
|
||||
|
||||
// Dimensions et positions
|
||||
--boite-position-basse: 1rem;
|
||||
--boite-longueur: 70ch;
|
||||
|
||||
// Marges
|
||||
--section-marges-internes: 1rem;
|
||||
|
||||
position: sticky; /* 1 */
|
||||
bottom: var(--boite-position-basse); /* 1 */
|
||||
overflow: visible;
|
||||
width: 0;
|
||||
height: 0;
|
||||
width: 0; /* 2 */
|
||||
height: 0; /* 2 */
|
||||
|
||||
&__conteneur {
|
||||
transform: translate(calc(50vw - 35ch), -100%);
|
||||
transform: translate(calc(50vw - var(--boite-longueur) / 2), -100%);
|
||||
display: grid;
|
||||
width: 70ch;
|
||||
max-width: 70ch;
|
||||
width: var(--boite-longueur);
|
||||
max-width: var(--boite-longueur);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
|
||||
/**
|
||||
* Définis les apparence et comportement de toutes les sections de la boîte.
|
||||
*/
|
||||
> section {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
background: rgb(255 255 255 / 90%);
|
||||
padding: var(--section-marges-internes);
|
||||
background: var(--boite-couleur-fond);
|
||||
|
||||
+ section {
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
|
|
@ -30,12 +51,13 @@
|
|||
.onglets-details-produit {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-rows: 1fr min-content;
|
||||
grid-template-rows: auto min-content;
|
||||
padding: initial;
|
||||
|
||||
> section {
|
||||
overflow-y: auto;
|
||||
grid-column: span 3;
|
||||
padding: 1rem;
|
||||
padding: var(--section-marges-internes);
|
||||
font-weight: 350;
|
||||
|
||||
&[hidden] {
|
||||
|
|
@ -64,29 +86,44 @@
|
|||
li {
|
||||
width: 100%;
|
||||
|
||||
&:first-of-type a {
|
||||
border-right-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
|
||||
&:last-of-type a {
|
||||
border-right-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: var(--espace-xs) 0;
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
border-top: 1px solid transparent;
|
||||
border-right: 1px solid var(--couleur-noir);
|
||||
border-left: 1px solid var(--couleur-noir);
|
||||
|
||||
&:first-of-type {
|
||||
border-left: initial;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-left: initial;
|
||||
}
|
||||
|
||||
/* Quand l'onglet est sélectionné */
|
||||
&[aria-selected="true"] {
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
&:focus, &:focus-visible {
|
||||
outline-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:has(section:not([hidden])) {
|
||||
grid-template-rows: 12lh min-content;
|
||||
|
||||
> ul li a:not([aria-selected="true"]) {
|
||||
border-top-color: var(--couleur-noir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Nom du Produit, sélecteur de variation et prix du Produit */
|
||||
|
|
|
|||
67
web/app/themes/haiku-atelier-2024/src/scripts/gaffe.ts
Normal file
67
web/app/themes/haiku-atelier-2024/src/scripts/gaffe.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Initialise GlitchTip.
|
||||
*/
|
||||
|
||||
import {
|
||||
breadcrumbsIntegration,
|
||||
BrowserClient,
|
||||
createTransport,
|
||||
dedupeIntegration,
|
||||
defaultStackParser,
|
||||
functionToStringIntegration,
|
||||
getCurrentScope,
|
||||
globalHandlersIntegration,
|
||||
httpContextIntegration,
|
||||
linkedErrorsIntegration,
|
||||
} from "@sentry/browser";
|
||||
import type { Transport } from "@sentry/types";
|
||||
|
||||
const makeFetchTransport = (options): Transport => {
|
||||
const makeRequest = async (request) => {
|
||||
const requestOptions: RequestInit = {
|
||||
body: request.body,
|
||||
headers: options.headers,
|
||||
method: "POST",
|
||||
mode: "no-cors",
|
||||
referrerPolicy: "no-referrer",
|
||||
...options.fetchOptions,
|
||||
};
|
||||
|
||||
const response = await fetch(options.url, requestOptions);
|
||||
return ({
|
||||
headers: {
|
||||
"x-sentry-rate-limits": response.headers.get("X-Sentry-Rate-Limits"),
|
||||
"retry-after": response.headers.get("Retry-After"),
|
||||
},
|
||||
statusCode: response.status,
|
||||
});
|
||||
};
|
||||
|
||||
return createTransport(options, makeRequest);
|
||||
};
|
||||
|
||||
/* Créé la configuration Sentry */
|
||||
const client = new BrowserClient({
|
||||
dsn: import.meta.env.VITE_GLITCHTIP_NSD,
|
||||
environment: "local",
|
||||
integrations: [
|
||||
breadcrumbsIntegration(),
|
||||
dedupeIntegration(),
|
||||
functionToStringIntegration(),
|
||||
globalHandlersIntegration(),
|
||||
httpContextIntegration(),
|
||||
linkedErrorsIntegration(),
|
||||
],
|
||||
stackParser: defaultStackParser,
|
||||
tracesSampleRate: 0.01,
|
||||
transport: makeFetchTransport,
|
||||
});
|
||||
|
||||
/* Initialise la configuration */
|
||||
getCurrentScope().setClient(client);
|
||||
client.init();
|
||||
|
||||
/* TODO: Retirer une fois les tests réalisés */
|
||||
setTimeout(() => {
|
||||
throw new Error("Test GlitchTip !");
|
||||
}, 3000);
|
||||
65
web/app/themes/haiku-atelier-2024/src/scripts/lib/api.ts
Normal file
65
web/app/themes/haiku-atelier-2024/src/scripts/lib/api.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { Right } from "purify-ts";
|
||||
import wretch from "wretch";
|
||||
import { ROUTE_API_PANIER } from "./constantes";
|
||||
|
||||
export const get = async (
|
||||
url: string,
|
||||
input: Record<string, string>,
|
||||
) => {
|
||||
return fetch(
|
||||
`${url}?${new URLSearchParams(input).toString()}`,
|
||||
);
|
||||
};
|
||||
|
||||
export const post = async (
|
||||
url: string,
|
||||
input: Record<string, string>,
|
||||
) => {
|
||||
return fetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
};
|
||||
|
||||
type CreateAPIMethod = <
|
||||
Input extends Record<string, string>,
|
||||
Output,
|
||||
>(opts: {
|
||||
url: string;
|
||||
method: "GET" | "POST";
|
||||
}) => (input: Input) => Promise<Output>;
|
||||
|
||||
const createAPIMethod: CreateAPIMethod = (opts) => (input) => {
|
||||
const method = opts.method === "GET" ? get : post;
|
||||
|
||||
return (
|
||||
method(opts.url, input)
|
||||
// Imagine error handling here...
|
||||
.then((res) => res.json())
|
||||
);
|
||||
};
|
||||
const requeteRecuperationPanierUtilisateur = fetch(
|
||||
ROUTE_API_PANIER,
|
||||
{
|
||||
credentials: "same-origin",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
method: "GET",
|
||||
mode: "same-origin",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
},
|
||||
).then(Right);
|
||||
|
||||
const recuperePanierUtilisateur = wretch(ROUTE_API_PANIER)
|
||||
.content("application/json")
|
||||
.options({
|
||||
credentials: "same-origin",
|
||||
mode: "same-origin",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
})
|
||||
.get()
|
||||
.json()
|
||||
.catch();
|
||||
|
||||
/**
|
||||
* Récupération du Panier. Pas de paramètres, juste une requête GET.
|
||||
*/
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
export const ATTRIBUT_ARIA_SELECTED = "aria-selected";
|
||||
export const ATTRIBUT_ARIA_HIDDEN = "aria-hidden";
|
||||
export const ATTRIBUT_HIDDEN = "hidden";
|
||||
|
||||
export const SELECTEUR_BOUTON_PANIER = ".compte-panier a[rel='cart']";
|
||||
export const SELECTEUR_SELECTEUR_QUANTITE = "#selecteur-variation";
|
||||
export const SELECTEUR_BOUTON_AJOUT_PANIER = "#bouton-ajout-panier";
|
||||
|
||||
export const CHEMIN_API_REST = "wp-json";
|
||||
export const ROUTE_API_PANIER = `/${CHEMIN_API_REST}/wc/store/cart`;
|
||||
export const ROUTE_API_AJOUTE_ARTICLE_PANIER = `/${CHEMIN_API_REST}/wc/store/cart/add-item`;
|
||||
|
|
@ -1,16 +1,69 @@
|
|||
export const safeQuerySelector = (parent: Document | Element) => (query: string) => {
|
||||
const element: Element | null = parent.querySelector(query);
|
||||
if (!element) throw new Error(`La requête "${query}" n'a débouché sur aucun Élément.`);
|
||||
import { Either, Left, Right } from "purify-ts";
|
||||
import { isEmpty, isNonNull, isNullish, pipe } from "remeda";
|
||||
import { creeSyntaxError, ERREUR_SELECTEUR_INEXISTANT, ERREUR_SYNTAXE_INVALIDE } from "./erreurs";
|
||||
|
||||
/** Type union des parents possible pour un `querySelector`. */
|
||||
type ElementParent = Document | Element;
|
||||
|
||||
/**
|
||||
* @param parent L'Élément parent dans lequel l'Élément souhaité sera recherché.
|
||||
* @param selecteur Le sélecteur de l'Élément recherché.
|
||||
*
|
||||
* @throws Une Erreur si aucun Élément n'a été trouvé.
|
||||
* @returns Un Élément.
|
||||
*/
|
||||
export const safeQuerySelector: (parent: ElementParent) => (selecteur: string) => Element = (parent) => (selecteur) => {
|
||||
const element: Element | null = parent.querySelector(selecteur);
|
||||
|
||||
if (!element) throw new DOMException(ERREUR_SELECTEUR_INEXISTANT(selecteur));
|
||||
return element;
|
||||
};
|
||||
|
||||
export const safeQuerySelectorAll = (parent: Document | Element) => (query: string) => {
|
||||
const elements: Element[] = Array.from(parent.querySelectorAll(query));
|
||||
if (!elements || elements.length === 0) throw new Error(`La requête "${query}" n'a débouché sur aucun Élément.`);
|
||||
return elements;
|
||||
};
|
||||
/**
|
||||
* @param parent L'Élément parent dans lequel l'Élément souhaité sera recherché.
|
||||
* @param selecteur Le sélecteur de l'Élément recherché.
|
||||
*
|
||||
* @returns Un tableau pouvant être vide d'Éléments.
|
||||
*/
|
||||
export const safeQuerySelectorAll: (parent: ElementParent) => (selecteur: string) => Element[] =
|
||||
(parent) => (selecteur) => {
|
||||
const elements: Element[] = Array.from(parent.querySelectorAll(selecteur));
|
||||
|
||||
export const estDansLaVue = (element: Element) => {
|
||||
if (isEmpty(elements)) {
|
||||
throw new DOMException(ERREUR_SELECTEUR_INEXISTANT(selecteur));
|
||||
}
|
||||
return elements;
|
||||
};
|
||||
|
||||
// export const recupereElementAvecSelecteur: (
|
||||
// parent: ElementParent,
|
||||
// ) => <T extends Element = Element>(selecteur: string) => Either<SyntaxError, T> = (parent) => (selecteur) =>
|
||||
export const recupereElementAvecSelecteur =
|
||||
(parent: ElementParent) => <E extends Element = Element>(selecteur: string): Either<SyntaxError, E> =>
|
||||
Either
|
||||
// Retourne une SyntaxError dans un Left si le sélecteur est invalide
|
||||
.encase(() => parent.querySelector<E>(selecteur))
|
||||
// Transforme le Left en une erreur plus sympathique
|
||||
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
||||
// Retourne une SyntaxError si l'Élément est null
|
||||
.chain((e: E | null) => isNonNull(e) ? Right(e) : Left(creeSyntaxError(ERREUR_SELECTEUR_INEXISTANT(selecteur))));
|
||||
|
||||
export const recupereElementsAvecSelecteur: (
|
||||
parent: ElementParent,
|
||||
) => (selecteur: string) => Either<SyntaxError, Element[]> = (parent) => (selecteur) =>
|
||||
Either
|
||||
// Retourne une SyntaxError dans un Left si le sélecteur est invalide
|
||||
.encase(() => pipe(parent.querySelectorAll(selecteur), Array.from<Element>))
|
||||
// Transforme le Left en une erreur plus sympathique
|
||||
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
||||
// Retourne une SyntaxError si le tableau est vide
|
||||
.chain(e => isEmpty(e) ? Left(creeSyntaxError(ERREUR_SELECTEUR_INEXISTANT(selecteur))) : Right(e));
|
||||
|
||||
/**
|
||||
* @param element
|
||||
* @returns Un booléen
|
||||
*/
|
||||
export const estDansLaVue: (element: Element) => boolean = (element) => {
|
||||
const rect: DOMRect = element.getBoundingClientRect();
|
||||
|
||||
return (
|
||||
|
|
|
|||
16
web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts
Normal file
16
web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Fonctions pour la création d'Erreurs.
|
||||
*/
|
||||
|
||||
/* Messages d'erreur */
|
||||
export const ERREUR_SYNTAXE_INVALIDE: (selecteur: string) => string = (selecteur) =>
|
||||
`Le selecteur "${selecteur}" est invalide`;
|
||||
export const ERREUR_SELECTEUR_INEXISTANT: (selecteur: string) => string = (selecteur) =>
|
||||
`La requête "${selecteur}" n'a retourné aucun Élément.`;
|
||||
|
||||
/* Création d'erreurs */
|
||||
export const creeSyntaxError: (message: string) => SyntaxError = (message) => new SyntaxError(message);
|
||||
|
||||
export const leveErreur: (erreur: Error) => never = (erreur) => {
|
||||
throw erreur;
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Fonctions liées à la gestion du Panier.
|
||||
*/
|
||||
|
||||
import { Either, EitherAsync, identity, Left, Right } from "purify-ts";
|
||||
import { ROUTE_API_PANIER } from "./constantes";
|
||||
|
||||
/** États utiles pour les scripts. */
|
||||
type Etats = {
|
||||
/** Un nonce pour l'authentification de requêtes API */
|
||||
nonce: string;
|
||||
};
|
||||
|
||||
// @ts-expect-error - États injectés par le modèle PHP
|
||||
const ETATS: Etats = _etats;
|
||||
|
||||
const requeteRecuperePanier = (): Promise<Either<Error, Response>> =>
|
||||
fetch(
|
||||
ROUTE_API_PANIER,
|
||||
{
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-WC-Store-API-Nonce": ETATS.nonce,
|
||||
},
|
||||
method: "GET",
|
||||
mode: "same-origin",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
},
|
||||
)
|
||||
.then(Right)
|
||||
.catch(Left);
|
||||
|
||||
export const recuperePanier = EitherAsync
|
||||
.fromPromise(requeteRecuperePanier)
|
||||
.map(a => a.json())
|
||||
.ifLeft(e => console.error(e));
|
||||
109
web/app/themes/haiku-atelier-2024/src/scripts/lib/test.lol.ts
Normal file
109
web/app/themes/haiku-atelier-2024/src/scripts/lib/test.lol.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import { Either, Left, Right } from "fp-ts/lib/Either";
|
||||
import { Errors, Type } from "io-ts";
|
||||
import { reporter } from "io-ts-reporters";
|
||||
|
||||
export async function fetchJson<T, O, I>(
|
||||
url: string,
|
||||
validator: Type<T, O, I>,
|
||||
init?: RequestInit,
|
||||
): Promise<Either<Error, T>> {
|
||||
try {
|
||||
const response = await fetch(url, init);
|
||||
const json: I = await response.json();
|
||||
const result = validator.decode(json);
|
||||
return result.fold<Either<Error, T>>(
|
||||
(errors: Errors) => {
|
||||
const messages = reporter(result);
|
||||
return new Left<Error, T>(new Error(messages.join("\n")));
|
||||
},
|
||||
(value: T) => {
|
||||
return new Right<Error, T>(value);
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
return Promise.resolve(new Left<Error, T>(err));
|
||||
}
|
||||
}
|
||||
|
||||
// the promise is never rejected
|
||||
// we handle the error with Either
|
||||
const readMailFromCli = async (): Promise<
|
||||
Either<{ errorReason: string }, string>
|
||||
> => {
|
||||
const rl = readline.createInterface({ input, output });
|
||||
return rl
|
||||
.question("Please enter your email \n")
|
||||
.then(Right)
|
||||
.catch((error) => Left({ errorReason: error.message }))
|
||||
.finally(() => {
|
||||
rl.close();
|
||||
});
|
||||
};
|
||||
|
||||
const validateEmail = (
|
||||
email: string,
|
||||
): Either<{ errorReason: string }, Email> => {
|
||||
if (!email.includes("@")) {
|
||||
return Left({ errorReason: "The email does not contain an @ character" });
|
||||
}
|
||||
|
||||
if (email.length < 3) {
|
||||
return Left({ errorReason: "The email be at least 3 characters long" });
|
||||
}
|
||||
|
||||
return Right(email);
|
||||
};
|
||||
|
||||
const getSessionIdFromEmail = (
|
||||
email: Email,
|
||||
): Promise<Either<{ errorReason: string }, SessionId>> => {
|
||||
// let’s simulate an API call
|
||||
return Promise.resolve(Right("12345"));
|
||||
};
|
||||
|
||||
const printInformations = ({
|
||||
email,
|
||||
sessionId,
|
||||
}: {
|
||||
email: Email;
|
||||
sessionId: SessionId;
|
||||
}): void => {
|
||||
console.log(`Email: ${email}; SessionId: ${sessionId}`);
|
||||
};
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const eitherEmailFromInput = await readMailFromCli(); // Returns an Either type
|
||||
|
||||
const eitherEmail = eitherEmailFromInput.map(validateEmail); // map over the either to validate the email
|
||||
|
||||
eitherEmail.caseOf({
|
||||
Left: (error) => console.log(error.errorReason), // email is invalid
|
||||
Right: async (email) => {
|
||||
const eitherSessionId = await getSessionIdFromEmail(email);
|
||||
eitherSessionId.caseOf({
|
||||
Left: (error) => console.log(error.errorReason), // getting the sessionId failed
|
||||
Right: (sessionId) => {
|
||||
printInformations({ sessionId, email });
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const flow = EitherAsync<{ errorReason: string }, void>(
|
||||
async ({ liftEither, fromPromise }) => {
|
||||
const emailFromInput = await fromPromise(readMailFromCli());
|
||||
const email = await liftEither(validateEmail(emailFromInput));
|
||||
const sessionId = await fromPromise(getSessionIdFromEmail(email));
|
||||
printInformations({ sessionId, email });
|
||||
},
|
||||
);
|
||||
|
||||
const main2 = async () => {
|
||||
const result = await flow.run();
|
||||
result.ifLeft((error) => {
|
||||
console.log(error.errorReason);
|
||||
});
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import type { Either } from "purify-ts";
|
||||
import { recupereElementAvecSelecteur, recupereElementsAvecSelecteur } from "./dom";
|
||||
|
||||
export const recupereElementsDocument: (selecteur: string) => Either<SyntaxError, Element[]> =
|
||||
recupereElementsAvecSelecteur(document);
|
||||
|
||||
export const recupereElementDocument: <E extends Element = Element>(selecteur: string) => Either<SyntaxError, E> =
|
||||
recupereElementAvecSelecteur(document);
|
||||
|
|
@ -1,19 +1,68 @@
|
|||
// Scripts pour la Page Produit
|
||||
|
||||
import { safeQuerySelectorAll } from "./lib/dom.js";
|
||||
import { Either, identity } from "purify-ts";
|
||||
import {
|
||||
ATTRIBUT_ARIA_SELECTED,
|
||||
ATTRIBUT_HIDDEN,
|
||||
ROUTE_API_AJOUTE_ARTICLE_PANIER,
|
||||
SELECTEUR_BOUTON_AJOUT_PANIER,
|
||||
SELECTEUR_BOUTON_PANIER,
|
||||
SELECTEUR_SELECTEUR_QUANTITE,
|
||||
} from "./lib/constantes";
|
||||
import { leveErreur } from "./lib/erreurs";
|
||||
import { recupereElementDocument, recupereElementsDocument } from "./lib/utils";
|
||||
import { WCStoreCartAddItemArgs } from "./types/cart-add-item";
|
||||
|
||||
/** États utiles pour les scripts de la page. */
|
||||
type Etats = {
|
||||
/** L'ID en base de données du Produit. */
|
||||
idProduit: number;
|
||||
/** Un nonce pour l'authentification de requêtes API */
|
||||
nonce: string;
|
||||
};
|
||||
type EnsembleLienContenu = [Element, Element];
|
||||
|
||||
const fermeToutesSections = (ensembleLiensContenus: EnsembleLienContenu[]) => {
|
||||
ensembleLiensContenus.forEach((ensemble) => {
|
||||
ensemble[0].setAttribute("aria-selected", "false");
|
||||
ensemble[1].setAttribute("hidden", "true");
|
||||
// @ts-expect-error - États injectés par le modèle PHP
|
||||
const ETATS: Etats = _etats;
|
||||
|
||||
/**
|
||||
* Déplie toutes les sections de la Boîte des Informations Produit en ajustant les attributs
|
||||
* correspondants.
|
||||
*/
|
||||
const deplieToutesSections: (ensembleLiensContenus: EnsembleLienContenu[]) => void = (ensembleLiensContenus) => {
|
||||
ensembleLiensContenus.forEach(ensemble => {
|
||||
ensemble[0].setAttribute(ATTRIBUT_ARIA_SELECTED, "false");
|
||||
ensemble[1].setAttribute(ATTRIBUT_HIDDEN, "true");
|
||||
});
|
||||
};
|
||||
|
||||
// Éléments d'intérêt
|
||||
/** Le « Bouton » vers le Panier dont le texte est un indicateur du nombre de Produits dedans. */
|
||||
const BOUTON_PANIER: Either<SyntaxError, HTMLAnchorElement> = recupereElementDocument<HTMLAnchorElement>(
|
||||
SELECTEUR_BOUTON_PANIER,
|
||||
);
|
||||
|
||||
const gereBoiteInformationsProduit = () => {
|
||||
const liensOnglets: Element[] = safeQuerySelectorAll(document)("a[role='tab']");
|
||||
const sectionsContenus: Element[] = safeQuerySelectorAll(document)("section[role='tabpanel']");
|
||||
/* Récupère les Éléments intéressants */
|
||||
const liensOnglets: Element[] = recupereElementsDocument("a[role='tab']").caseOf({
|
||||
Left: leveErreur,
|
||||
Right: identity,
|
||||
});
|
||||
const sectionsContenus: Element[] = recupereElementsDocument("section[role='tabpanel']").caseOf({
|
||||
Left: leveErreur,
|
||||
Right: identity,
|
||||
});
|
||||
const selecteurQuantite: HTMLSelectElement = recupereElementDocument<HTMLSelectElement>(SELECTEUR_SELECTEUR_QUANTITE)
|
||||
.caseOf({
|
||||
Left: leveErreur,
|
||||
Right: identity,
|
||||
});
|
||||
const boutonAjoutPanier: HTMLButtonElement = recupereElementDocument<HTMLButtonElement>(SELECTEUR_BOUTON_AJOUT_PANIER)
|
||||
.caseOf({
|
||||
Left: leveErreur,
|
||||
Right: identity,
|
||||
});
|
||||
|
||||
const onglets = new Map<string, EnsembleLienContenu>();
|
||||
|
||||
/* Créé la Map avec les ensembles Lien-Contenu */
|
||||
|
|
@ -35,21 +84,74 @@ const gereBoiteInformationsProduit = () => {
|
|||
e.preventDefault();
|
||||
|
||||
/* Sauvegarde l'état d'ouverture de la section avant de toutes les fermer */
|
||||
const estAncienOngletCourant: boolean = v[0].getAttribute("aria-selected") === "true";
|
||||
fermeToutesSections(Array.from(onglets.values()));
|
||||
const estAncienOngletCourant: boolean = v[0].getAttribute(ATTRIBUT_ARIA_SELECTED) === "true";
|
||||
deplieToutesSections(Array.from(onglets.values()));
|
||||
|
||||
/* Ne fais rien de plus si l'onglet sélectionné était le courant */
|
||||
if (estAncienOngletCourant) return;
|
||||
|
||||
/* Ouvre le nouvel onglet sélectionné */
|
||||
v[0].setAttribute("aria-selected", "true");
|
||||
v[1].removeAttribute("hidden");
|
||||
v[0].setAttribute(ATTRIBUT_ARIA_SELECTED, "true");
|
||||
v[1].removeAttribute(ATTRIBUT_HIDDEN);
|
||||
});
|
||||
});
|
||||
|
||||
/* Ajout des Écouteurs d'Événements */
|
||||
selecteurQuantite.addEventListener("change", (e) => {
|
||||
/* e peut être null ou "--" ou autre chose */
|
||||
console.debug(selecteurQuantite.value, e);
|
||||
});
|
||||
boutonAjoutPanier.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
ajouteProduitAuPanier();
|
||||
});
|
||||
|
||||
console.debug(onglets);
|
||||
};
|
||||
|
||||
// TODO: Traiter le cas des Produits avec variations
|
||||
const ajouteProduitAuPanier = () => {
|
||||
const requeteInvalide: WCStoreCartAddItemArgs = {
|
||||
quantity: 1,
|
||||
id: ETATS.idProduit,
|
||||
};
|
||||
|
||||
// TODO: Traiter les cas d'erreurs avec ts-pattern
|
||||
/* Exécution de la requête */
|
||||
Either
|
||||
.encase<Error, WCStoreCartAddItemArgs>(() => WCStoreCartAddItemArgs(requeteInvalide))
|
||||
.ifLeft(e => console.error(e))
|
||||
.map(r => {
|
||||
fetch(
|
||||
ROUTE_API_AJOUTE_ARTICLE_PANIER,
|
||||
{
|
||||
body: JSON.stringify(r),
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-WC-Store-API-Nonce": ETATS.nonce,
|
||||
},
|
||||
method: "POST",
|
||||
mode: "same-origin",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
},
|
||||
)
|
||||
.then(a => a.json())
|
||||
.then(a => {
|
||||
BOUTON_PANIER
|
||||
.caseOf({
|
||||
Left: (e) => console.error("Le bouton du Panier n'existe pas !", e),
|
||||
Right: (r) => {
|
||||
console.debug(r);
|
||||
r.textContent = `cart ${a.items.length}`;
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(b => console.error(b));
|
||||
});
|
||||
};
|
||||
|
||||
/* Fonctions utilitaires */
|
||||
|
||||
// const creeObservateurIntersection = (element: Element, options: IntersectionObserverInit, classe = "anime") => {
|
||||
|
|
@ -76,4 +178,5 @@ const gereBoiteInformationsProduit = () => {
|
|||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
gereBoiteInformationsProduit();
|
||||
// recuperePanierUtilisateur();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
import * as v from "valibot";
|
||||
|
||||
const WCStoreCartAddItemArgsItemsSchema = v.object({
|
||||
/** Variation attribute name. */
|
||||
attribute: v.string(),
|
||||
/** Variation attribute value. */
|
||||
value: v.string(),
|
||||
});
|
||||
|
||||
const WCStoreCartAddItemArgsSchema = v.object({
|
||||
/** The basket item product or variation ID. */
|
||||
id: v.optional(v.number()),
|
||||
/** Quantity of this item to add to the basket. */
|
||||
quantity: v.optional(v.number()),
|
||||
/** Chosen attributes (for variations). */
|
||||
variation: v.optional(v.array(WCStoreCartAddItemArgsItemsSchema)),
|
||||
});
|
||||
|
||||
export type WCStoreCartAddItemArgsItems = v.InferOutput<typeof WCStoreCartAddItemArgsItemsSchema>;
|
||||
export type WCStoreCartAddItemArgs = v.InferOutput<typeof WCStoreCartAddItemArgsSchema>;
|
||||
|
||||
export const WCStoreCartAddItemArgs: (args: unknown) => WCStoreCartAddItemArgs = (args) =>
|
||||
v.parse(WCStoreCartAddItemArgsSchema, args);
|
||||
12
web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts
vendored
Normal file
12
web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
/** URL du site. */
|
||||
readonly VITE_URL: string;
|
||||
/** URL du endpoint pour le report d'Erreurs au service GlitchTip. */
|
||||
readonly VITE_GLITCHTIP_NSD: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
<section class="actions-produit">
|
||||
{# TODO: Ajouter au Panier sans rafraîchir la Page #}
|
||||
<button class="bouton-case-pleine desactive" type="button">Add to cart</button>
|
||||
<button class="bouton-case-pleine desactive" id="bouton-ajout-panier" type="button">Add to cart</button>
|
||||
</section>
|
||||
</div>
|
||||
</aside>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,23 @@
|
|||
{% extends "base.twig" %}
|
||||
|
||||
{% block head %}
|
||||
<script>
|
||||
// Injection d'états pour les Scripts de la page.
|
||||
|
||||
/**
|
||||
* @typedef {Object} Etats - États utiles pour les scripts de la page.
|
||||
* @property {number} idProduit - L'ID en base de données du Produit.
|
||||
* @property {string} nonce - Un nonce pour l'authentification de requêtes API.
|
||||
*/
|
||||
|
||||
/** @type {Etats} */
|
||||
const _etats = {
|
||||
idProduit: {{ produit.id }},
|
||||
nonce: "{{ nonce }}",
|
||||
};
|
||||
</script>
|
||||
{% endblock head %}
|
||||
|
||||
{% block contenu %}
|
||||
{# Menu des catégories de Produits #}
|
||||
{% include "parts/menu-categories-produits.twig" %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue