2024-12-12
This commit is contained in:
parent
ac0efab9b2
commit
0c39c95625
45 changed files with 827 additions and 319 deletions
|
|
@ -66,7 +66,7 @@
|
|||
);
|
||||
--contenu-page-hauteur-minimale-avec-categories: calc(
|
||||
100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur)
|
||||
- var(--menu-categories-produits-hauteur)
|
||||
- var(--menu-categories-produits-hauteur)
|
||||
);
|
||||
/* Espacements */
|
||||
--espace-xs: 0.25rem;
|
||||
|
|
@ -248,8 +248,8 @@ button.bouton-retour-haut {
|
|||
background: var(--couleur-fond);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
border-radius: 100%;
|
||||
transition: 0.2s background, 0.2s opacity, 0.2s visibility;
|
||||
box-shadow: initial;
|
||||
transition: 0.2s background, 0.2s opacity, 0.2s visibility;
|
||||
}
|
||||
button.bouton-retour-haut img {
|
||||
width: 1rem;
|
||||
|
|
@ -267,8 +267,17 @@ button.bouton-retour-haut[data-actif] {
|
|||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
all: initial;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin-top: var(--espace-l);
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
padding: var(--espace-xs);
|
||||
accent-color: var(--couleur-jaune);
|
||||
background: var(--couleur-gris);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
outline: 2px solid transparent;
|
||||
|
|
@ -340,6 +349,25 @@ label:has(~ input[type=checkbox], ~ input[type=radio]), input[type=checkbox] + l
|
|||
}
|
||||
}
|
||||
|
||||
input[type=radio] {
|
||||
appearance: initial;
|
||||
border-radius: 100%;
|
||||
}
|
||||
input[type=radio]:checked {
|
||||
display: inline-flex;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
}
|
||||
input[type=radio]:checked::before {
|
||||
content: " ";
|
||||
inset: initial;
|
||||
display: inline-block;
|
||||
width: calc(var(--espace-l) / 2);
|
||||
height: calc(var(--espace-l) / 2);
|
||||
background: var(--couleur-noir);
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
textarea:focus-visible, textarea:focus-within {
|
||||
outline: 1px solid var(--couleur-noir);
|
||||
}
|
||||
|
|
@ -612,9 +640,9 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
|||
background: transparent;
|
||||
}
|
||||
#en-tete .logo img {
|
||||
image-rendering: crisp-edges;
|
||||
shape-rendering: geometricPrecision;
|
||||
object-fit: contain;
|
||||
image-rendering: crisp-edges;
|
||||
shape-rendering: geometricprecision;
|
||||
}
|
||||
#en-tete .logo button {
|
||||
display: block;
|
||||
|
|
@ -1052,8 +1080,8 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
|||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
padding: var(--espace-m);
|
||||
margin-bottom: var(--espace-xl);
|
||||
padding: var(--espace-m);
|
||||
}
|
||||
.grille-produits article figure figcaption h3 {
|
||||
font-style: italic;
|
||||
|
|
@ -1450,9 +1478,9 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
|||
max-width: 100vw;
|
||||
height: var(--pied-de-page-hauteur);
|
||||
padding: var(--espace-m);
|
||||
font-size: 0.8rem;
|
||||
background: var(--couleur-jaune);
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
#pied-de-page .zone-menu-navigation-secondaire {
|
||||
justify-self: start;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-a-propos.scss"],"names":[],"mappings":"AAEA;EAEE;EAGA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;AACA;AACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIA;AACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAIJ;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EAEA;;AAGF;EACE;EAEA;;AAEA;EACE;;AAIJ;EACE;EAEA;;AAGF;EACE;EAEA;;AAGF;EACE;EAEA;;AAEA;EACE;;AAMR;EA3LF;IA4LI;;;;AAIJ;EACE;IACE","file":"page-a-propos.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-a-propos.scss"],"names":[],"mappings":"AAEA;EAEE;EAGA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;AAEA;AAEA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIA;AACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAIJ;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EAEA;;AAGF;EACE;EAEA;;AAEA;EACE;;AAIJ;EACE;EAEA;;AAGF;EACE;EAEA;;AAGF;EACE;EAEA;;AAEA;EACE;;AAMR;EA7LF;IA8LI;;;;AAIJ;EACE;IACE","file":"page-a-propos.css"}
|
||||
|
|
@ -46,12 +46,6 @@
|
|||
.page-modele-simple .contenu__textuel p + p {
|
||||
margin-top: var(--espace-m);
|
||||
}
|
||||
@media (width <= 50rem) {
|
||||
.page-modele-simple .contenu {
|
||||
border-right: initial;
|
||||
border-left: initial;
|
||||
}
|
||||
}
|
||||
.page-modele-simple#page-cgv .contenu {
|
||||
font-style: normal;
|
||||
}
|
||||
|
|
@ -59,8 +53,8 @@
|
|||
font-style: italic;
|
||||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel {
|
||||
padding: 0;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel__section {
|
||||
width: 100%;
|
||||
|
|
@ -70,10 +64,10 @@
|
|||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel__section header {
|
||||
width: 100%;
|
||||
margin-bottom: var(--espace-l);
|
||||
padding: var(--espace-m) var(--espace-xl);
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
border-bottom: 1px solid var(--couleur-noir);
|
||||
margin-bottom: var(--espace-l);
|
||||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel__section header h3 {
|
||||
width: fit-content;
|
||||
|
|
@ -83,9 +77,9 @@
|
|||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel__section ul {
|
||||
margin-bottom: 1lh;
|
||||
padding: 0 var(--espace-xl);
|
||||
list-style: square;
|
||||
list-style-position: inside;
|
||||
padding: 0 var(--espace-xl);
|
||||
}
|
||||
.page-modele-simple#page-cgv .contenu__textuel__section p {
|
||||
padding: 0 var(--espace-xl);
|
||||
|
|
@ -93,5 +87,11 @@
|
|||
.page-modele-simple#page-cgv .contenu__textuel__section p:last-of-type {
|
||||
margin-bottom: var(--espace-xl);
|
||||
}
|
||||
@media (width <= 50rem) {
|
||||
.page-modele-simple .contenu {
|
||||
border-right: initial;
|
||||
border-left: initial;
|
||||
}
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=page-modele-simple.css.map */
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-modele-simple.scss"],"names":[],"mappings":"AAEA;EAEE;AAAA;AAAA;EAKA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKN;EACE;IACE;IACA;;;AAKF;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;;AAGE;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAKF;EACE;;AAEA;EACE","file":"page-modele-simple.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-modele-simple.scss"],"names":[],"mappings":"AAEA;EAEE;AAAA;AAAA;EAKA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMJ;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;;AAGE;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAKF;EACE;;AAEA;EACE;;AAQZ;EACE;IACE;IACA","file":"page-modele-simple.css"}
|
||||
|
|
@ -1 +1 @@
|
|||
.page-modele-simple{--page-hauteur-minimale:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur) - var(--espace-xl) - 1px);--page-marges-bloc-debut:var(--en-tete-hauteur);margin-top:var(--page-marges-bloc-debut);margin-bottom:var(--espace-xl);border-bottom:1px solid var(--couleur-noir);flex-flow:column;display:flex}.page-modele-simple .contenu{width:min(50rem,100%);min-height:var(--page-hauteur-minimale);border:1px solid var(--couleur-noir);border-bottom:initial;flex-flow:column;place-items:center;margin:auto;font-style:italic;font-weight:400;display:flex}.page-modele-simple .contenu__en-tete{width:100%;padding:var(--espace-m)var(--espace-xl);color:var(--couleur-blanc);background:var(--couleur-noir)}.page-modele-simple .contenu__en-tete h2{text-transform:uppercase;width:fit-content;letter-spacing:var(--espacement-inter-lettres-etendu-l);margin:auto}.page-modele-simple .contenu__textuel{max-width:34rem;height:100%;padding:0 var(--espace-xl);text-wrap:pretty;flex-flow:column;flex:1;place-content:center;display:flex}.page-modele-simple .contenu__textuel p+p{margin-top:var(--espace-m)}@media (width<=50rem){.page-modele-simple .contenu{border-right:initial;border-left:initial}}.page-modele-simple#page-cgv .contenu{font-style:normal}.page-modele-simple#page-cgv .contenu header{font-style:italic}.page-modele-simple#page-cgv .contenu__textuel{max-width:initial;padding:0}.page-modele-simple#page-cgv .contenu__textuel__section{width:100%}.page-modele-simple#page-cgv .contenu__textuel__section:first-of-type header{border-top:initial}.page-modele-simple#page-cgv .contenu__textuel__section header{width:100%;padding:var(--espace-m)var(--espace-xl);border-top:1px solid var(--couleur-noir);border-bottom:1px solid var(--couleur-noir);margin-bottom:var(--espace-l)}.page-modele-simple#page-cgv .contenu__textuel__section header h3{text-transform:uppercase;width:fit-content;letter-spacing:var(--espacement-inter-lettres-etendu-l);margin:auto}.page-modele-simple#page-cgv .contenu__textuel__section ul{padding:0 var(--espace-xl);margin-bottom:1lh;list-style:square inside}.page-modele-simple#page-cgv .contenu__textuel__section p{padding:0 var(--espace-xl)}.page-modele-simple#page-cgv .contenu__textuel__section p:last-of-type{margin-bottom:var(--espace-xl)}
|
||||
.page-modele-simple{--page-hauteur-minimale:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur) - var(--espace-xl) - 1px);--page-marges-bloc-debut:var(--en-tete-hauteur);margin-top:var(--page-marges-bloc-debut);margin-bottom:var(--espace-xl);border-bottom:1px solid var(--couleur-noir);flex-flow:column;display:flex}.page-modele-simple .contenu{width:min(50rem,100%);min-height:var(--page-hauteur-minimale);border:1px solid var(--couleur-noir);border-bottom:initial;flex-flow:column;place-items:center;margin:auto;font-style:italic;font-weight:400;display:flex}.page-modele-simple .contenu__en-tete{width:100%;padding:var(--espace-m)var(--espace-xl);color:var(--couleur-blanc);background:var(--couleur-noir)}.page-modele-simple .contenu__en-tete h2{text-transform:uppercase;width:fit-content;letter-spacing:var(--espacement-inter-lettres-etendu-l);margin:auto}.page-modele-simple .contenu__textuel{max-width:34rem;height:100%;padding:0 var(--espace-xl);text-wrap:pretty;flex-flow:column;flex:1;place-content:center;display:flex}.page-modele-simple .contenu__textuel p+p{margin-top:var(--espace-m)}.page-modele-simple#page-cgv .contenu{font-style:normal}.page-modele-simple#page-cgv .contenu header{font-style:italic}.page-modele-simple#page-cgv .contenu__textuel{max-width:initial;padding:0}.page-modele-simple#page-cgv .contenu__textuel__section{width:100%}.page-modele-simple#page-cgv .contenu__textuel__section:first-of-type header{border-top:initial}.page-modele-simple#page-cgv .contenu__textuel__section header{width:100%;margin-bottom:var(--espace-l);padding:var(--espace-m)var(--espace-xl);border-top:1px solid var(--couleur-noir);border-bottom:1px solid var(--couleur-noir)}.page-modele-simple#page-cgv .contenu__textuel__section header h3{text-transform:uppercase;width:fit-content;letter-spacing:var(--espacement-inter-lettres-etendu-l);margin:auto}.page-modele-simple#page-cgv .contenu__textuel__section ul{padding:0 var(--espace-xl);margin-bottom:1lh;list-style:square inside}.page-modele-simple#page-cgv .contenu__textuel__section p{padding:0 var(--espace-xl)}.page-modele-simple#page-cgv .contenu__textuel__section p:last-of-type{margin-bottom:var(--espace-xl)}@media (width<=50rem){.page-modele-simple .contenu{border-right:initial;border-left:initial}}
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
margin-top: var(--espace-m);
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux {
|
||||
width: min(30rem, 100%);
|
||||
width: min(40rem, 100%);
|
||||
margin: auto;
|
||||
padding: var(--espace-l) var(--espace-xl);
|
||||
text-align: center;
|
||||
|
|
@ -165,6 +165,27 @@
|
|||
#panneau-panier .panneau__sous-totaux__ligne#sous-total-livraison p:last-of-type span {
|
||||
color: grey;
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux__choix-methode-livraison {
|
||||
flex-flow: row wrap;
|
||||
gap: var(--espace-xs) var(--espace-m);
|
||||
justify-content: center;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: inherit;
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux__choix-methode-livraison > label:first-of-type {
|
||||
cursor: revert;
|
||||
flex-basis: 100%;
|
||||
margin-bottom: var(--espace-xs);
|
||||
color: grey;
|
||||
text-align: center;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux__choix-methode-livraison div {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
column-gap: 1ch;
|
||||
place-items: center;
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux__conditions-livraison {
|
||||
margin-top: var(--espace-l);
|
||||
font-size: 0.8rem;
|
||||
|
|
@ -200,7 +221,8 @@
|
|||
#panneau-panier .panneau__instructions-code-promo {
|
||||
padding: var(--espace-xl) var(--espace-l);
|
||||
}
|
||||
#panneau-panier .panneau__instructions-code-promo .panneau__instructions-code-promo__code-promo input, #panneau-panier .panneau__instructions-code-promo .panneau__instructions-code-promo__code-promo button {
|
||||
#panneau-panier .panneau__instructions-code-promo .panneau__instructions-code-promo__code-promo input,
|
||||
#panneau-panier .panneau__instructions-code-promo .panneau__instructions-code-promo__code-promo button {
|
||||
flex: 1;
|
||||
}
|
||||
#panneau-panier .panneau__sous-totaux {
|
||||
|
|
@ -325,8 +347,8 @@
|
|||
#panneau-informations-client .panneau__pied-de-page {
|
||||
align-content: center;
|
||||
padding: var(--espace-l) 0;
|
||||
font-style: italic;
|
||||
font-size: 1.25rem;
|
||||
font-style: italic;
|
||||
color: var(--couleur-blanc);
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/layouts/_panneau-panier.scss","../../../src/sass/layouts/_panneau-informations-client.scss","../../../src/sass/pages/page-panier.scss"],"names":[],"mappings":";AAEA;EACE;;AAEA;EACE;;AAIF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;AAEA;AASA;AAAA;AAAA;AAAA;AAkBA;AASA;;AAnCA;EACE;EACA;EACA;EACA;EACA;;AAOF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAOR;EACE;EACA;EACA;EACA;AAEA;AAAA;AAAA;AAAA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKA;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;IACE;;EAGF;IACE;;EAEA;IACE;;EAIJ;IACE;;EAGE;IACE;;EAKN;IACE;;;;AC1PN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIF;EAEE;EACA;EACA;EAGA;EAEA;EACA;;AAEA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAMN;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;;AAMR;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;IACE;;;;ACpKN;AAAA;AAAA;AAAA;AAIA;AACE;EACA;AAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAKF;EACE;;AAGF;EACE","file":"page-panier.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/layouts/_panneau-panier.scss","../../../src/sass/layouts/_panneau-informations-client.scss","../../../src/sass/pages/page-panier.scss"],"names":[],"mappings":";AAEA;EACE;;AAEA;EACE;;AAIF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;AAEA;AASA;AAAA;AAAA;AAAA;AAmBA;AASA;;AApCA;EACE;EACA;EACA;EACA;EACA;;AAOF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAOR;EACE;EACA;EACA;EACA;AAEA;AAAA;AAAA;AAAA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKA;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAOJ;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;IACE;;EAGF;IACE;;EAEA;IACE;;EAIJ;IACE;;EAGE;AAAA;IAEE;;EAKN;IACE;;;;ACvRN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIF;EAEE;EACA;EACA;EAGA;EAEA;EACA;;AAEA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAMN;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;;AAMR;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;IACE;;;;ACpKN;AAAA;AAAA;AAAA;AAIA;AACE;EACA;AAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAKF;EACE;;AAGF;EACE","file":"page-panier.css"}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -94,9 +94,9 @@ $sous_total_panier = WC()->cart->get_subtotal();
|
|||
/** @var string|null $code_promo Le code promo appliqué au Panier s'il existe. */
|
||||
$code_promo = collect(WC()->cart->get_applied_coupons())->first();
|
||||
/** @var int $sous_total_reduction Le total du montant de la Réduction appliquée au Panier */
|
||||
$sous_total_reduction = Number::format(WC()->cart->get_totals()["discount_total"], precision: 2);
|
||||
$sous_total_reduction = Number::format(WC()->cart->get_totals()["discount_total"], maxPrecision: 2);
|
||||
/** @var float $total_panier Le total de la Commande dans le Panier. */
|
||||
$total_panier = Number::format(floatval(WC()->cart->get_totals()["total"]), precision: 2);
|
||||
$total_panier = Number::format(floatval(WC()->cart->get_totals()["total"]), maxPrecision: 2);
|
||||
|
||||
foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) {
|
||||
$panier[$cle_panier] = [
|
||||
|
|
@ -122,17 +122,24 @@ foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) {
|
|||
$email = WC()->customer->get_billing_email();
|
||||
$adresse_livraison = WC()->customer->get_shipping();
|
||||
$adresse_facturation = WC()->customer->get_billing();
|
||||
$adresse_renseignee = $adresse_livraison["city"] != "";
|
||||
$pays_livraison = collect(WC()->countries->get_countries())->only($pays_acceptes)->toArray();
|
||||
$total_livraison = Number::format(floatval(WC()->cart->get_totals()["shipping_total"]), precision: 0);
|
||||
|
||||
// echo "<pre>";
|
||||
// print_r(WC()->countries->get_countries());
|
||||
// print_r($adresse_livraison);
|
||||
// echo "</pre>";
|
||||
$methodes_livraison = collect(WC()->session->get("shipping_for_package_0")["rates"])
|
||||
->values()
|
||||
->map(function (WC_Shipping_Rate $methode) {
|
||||
return [
|
||||
"id" => $methode->get_method_id(),
|
||||
"prix" => Number::format(intval($methode->get_cost()), maxPrecision: 2),
|
||||
"selectionnee" => collect(WC()->session->get("chosen_shipping_methods"))->first() == $methode->get_id(),
|
||||
"titre" => $methode->get_label(),
|
||||
];
|
||||
});
|
||||
|
||||
$contexte["email"] = $email;
|
||||
$contexte["adresse_livraison"] = $adresse_livraison;
|
||||
$contexte["adresse_facturation"] = $adresse_facturation;
|
||||
$contexte["adresse_renseignee"] = $adresse_renseignee;
|
||||
$contexte["sous_total_panier"] = $sous_total_panier;
|
||||
$contexte["code_promo"] = $code_promo;
|
||||
$contexte["sous_total_reduction"] = $sous_total_reduction;
|
||||
|
|
@ -140,10 +147,12 @@ $contexte["total_panier"] = $total_panier;
|
|||
$contexte["produits_panier"] = $panier;
|
||||
$contexte["pays_livraison"] = $pays_livraison;
|
||||
$contexte["sous_total_livraison"] = $total_livraison;
|
||||
$contexte["methode_livraison"] =
|
||||
collect(WC()->session->get("shipping_for_package_0")["rates"])
|
||||
->first()
|
||||
?->get_label() ?? "";
|
||||
$contexte["methodes_livraison"] = $methodes_livraison;
|
||||
|
||||
// echo "<pre>";
|
||||
// print_r($methodes_livraison);
|
||||
// print_r(WC()->session->get("chosen_shipping_methods"));
|
||||
// echo "</pre>";
|
||||
|
||||
// Charge les scripts et styles de la page
|
||||
function charge_scripts_styles_page_panier(): void {
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ button {
|
|||
background: var(--couleur-fond);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
border-radius: 100%;
|
||||
transition: 0.2s background, 0.2s opacity, 0.2s visibility;
|
||||
box-shadow: initial;
|
||||
transition: 0.2s background, 0.2s opacity, 0.2s visibility;
|
||||
|
||||
img {
|
||||
width: 1rem;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,16 @@
|
|||
// Styles de base pour les éléments de formulaires.
|
||||
|
||||
fieldset {
|
||||
all: initial;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin-top: var(--espace-l);
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
padding: var(--espace-xs);
|
||||
accent-color: var(--couleur-jaune);
|
||||
background: var(--couleur-gris);
|
||||
border: 1px solid var(--couleur-noir);
|
||||
outline: 2px solid transparent;
|
||||
|
|
@ -93,6 +102,27 @@ input[type="checkbox"], input[type="radio"] {
|
|||
}
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
appearance: initial;
|
||||
border-radius: 100%;
|
||||
|
||||
&:checked {
|
||||
display: inline-flex;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
|
||||
&::before {
|
||||
content: " ";
|
||||
inset: initial;
|
||||
display: inline-block;
|
||||
width: calc(var(--espace-l) / 2);
|
||||
height: calc(var(--espace-l) / 2);
|
||||
background: var(--couleur-noir);
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
&:focus-visible, &:focus-within {
|
||||
outline: 1px solid var(--couleur-noir);
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
}
|
||||
|
||||
img {
|
||||
image-rendering: crisp-edges;
|
||||
shape-rendering: geometricPrecision;
|
||||
object-fit: contain;
|
||||
image-rendering: crisp-edges;
|
||||
shape-rendering: geometricprecision;
|
||||
}
|
||||
|
||||
button {
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@
|
|||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
padding: var(--espace-m);
|
||||
margin-bottom: var(--espace-xl);
|
||||
padding: var(--espace-m);
|
||||
|
||||
h3 {
|
||||
font-style: italic;
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@
|
|||
.panneau__pied-de-page {
|
||||
align-content: center;
|
||||
padding: var(--espace-l) 0;
|
||||
font-style: italic;
|
||||
font-size: 1.25rem;
|
||||
font-style: italic;
|
||||
color: var(--couleur-blanc);
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@
|
|||
}
|
||||
|
||||
.panneau__sous-totaux {
|
||||
width: min(30rem, 100%);
|
||||
width: min(40rem, 100%);
|
||||
margin: auto;
|
||||
padding: var(--espace-l) var(--espace-xl);
|
||||
text-align: center;
|
||||
|
|
@ -199,6 +199,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
&__choix-methode-livraison {
|
||||
flex-flow: row wrap;
|
||||
gap: var(--espace-xs) var(--espace-m);
|
||||
justify-content: center;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: inherit;
|
||||
|
||||
> label:first-of-type {
|
||||
cursor: revert;
|
||||
flex-basis: 100%;
|
||||
margin-bottom: var(--espace-xs);
|
||||
color: grey;
|
||||
text-align: center;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
column-gap: 1ch;
|
||||
place-items: center;
|
||||
|
||||
input {}
|
||||
}
|
||||
}
|
||||
|
||||
&__conditions-livraison {
|
||||
margin-top: var(--espace-l);
|
||||
font-size: 0.8rem;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
max-width: 100vw;
|
||||
height: var(--pied-de-page-hauteur);
|
||||
padding: var(--espace-m);
|
||||
font-size: 0.8rem;
|
||||
background: var(--couleur-jaune);
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
font-size: 0.8rem;
|
||||
|
||||
// Liens vers les pages du site
|
||||
.zone-menu-navigation-secondaire {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
pointer-events: none;
|
||||
display: block;
|
||||
width: 1.75rem;
|
||||
|
||||
/* filter: drop-shadow(1px 1px 3px var(--couleur-gris-fonce)); */
|
||||
|
||||
/* transition: 0.2s filter; */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,13 +57,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media (width <= 50rem) {
|
||||
.contenu {
|
||||
border-right: initial;
|
||||
border-left: initial;
|
||||
}
|
||||
}
|
||||
|
||||
&#page-cgv {
|
||||
.contenu {
|
||||
font-style: normal;
|
||||
|
|
@ -73,8 +66,8 @@
|
|||
}
|
||||
|
||||
&__textuel {
|
||||
padding: 0;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
|
||||
&__section {
|
||||
width: 100%;
|
||||
|
|
@ -87,10 +80,10 @@
|
|||
|
||||
header {
|
||||
width: 100%;
|
||||
margin-bottom: var(--espace-l);
|
||||
padding: var(--espace-m) var(--espace-xl);
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
border-bottom: 1px solid var(--couleur-noir);
|
||||
margin-bottom: var(--espace-l);
|
||||
|
||||
h3 {
|
||||
width: fit-content;
|
||||
|
|
@ -102,9 +95,9 @@
|
|||
|
||||
ul {
|
||||
margin-bottom: 1lh;
|
||||
padding: 0 var(--espace-xl);
|
||||
list-style: square;
|
||||
list-style-position: inside;
|
||||
padding: 0 var(--espace-xl);
|
||||
|
||||
li {}
|
||||
}
|
||||
|
|
@ -120,4 +113,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 50rem) {
|
||||
.contenu {
|
||||
border-right: initial;
|
||||
border-left: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = "button.detail-produit__ac
|
|||
export const SELECTEUR_BOUTON_SUPPRESSION_PANIER = "button.detail-produit__actions__suppression";
|
||||
export const SELECTEUR_CHAMP_CODE_PROMO = "#panneau-panier #champ-code-promo";
|
||||
export const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = "input";
|
||||
export const SELECTEUR_CONTENEUR_METHODES_LIVRAISON = "#panneau-panier #choix-methode-livraison";
|
||||
export const SELECTEUR_ENSEMBLE_CODE_PROMO = "#panneau-panier #ensemble-code-promo";
|
||||
export const SELECTEUR_ENTREES_PANIER = "article";
|
||||
export const SELECTEUR_FORMULAIRE_FACTURATION = "#panneau-informations-client .panneau__formulaires__facturation";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
export const ADRESSES_MAJ = "adressesMaj";
|
||||
export const CODE_PROMO_MAJ = "codePromoMaj";
|
||||
export const METHODES_LIVRAISON_MAJ = "methodesLivraisonMaj";
|
||||
export const PRODUITS_MAJ = "produitsMaj";
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { ADRESSES_MAJ, CODE_PROMO_MAJ, METHODES_LIVRAISON_MAJ, PRODUITS_MAJ } from "../../constantes/evenements";
|
||||
|
||||
export const ADRESSES_MAJ_EVENT = new CustomEvent(ADRESSES_MAJ, {});
|
||||
export const CODE_PROMO_MAJ_EVENT = new CustomEvent(CODE_PROMO_MAJ, {});
|
||||
|
||||
export class MagasinPanier extends EventTarget {
|
||||
emetAdressesMaj(): void {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(ADRESSES_MAJ),
|
||||
);
|
||||
}
|
||||
|
||||
emetCodePromoMaj(): void {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(CODE_PROMO_MAJ),
|
||||
);
|
||||
}
|
||||
|
||||
emetMethodesLivraisonMaj(): void {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(METHODES_LIVRAISON_MAJ),
|
||||
);
|
||||
}
|
||||
|
||||
emetProduitsMaj(): void {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(PRODUITS_MAJ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import type { GenericSchema, InferOutput, ValiError } from "valibot";
|
||||
|
||||
import { type Either, Maybe } from "purify-ts";
|
||||
|
||||
import { eitherJsonParse } from "./dom.ts";
|
||||
import { ErreurEntreeInexistante, type NonExistingKeyError } from "./erreurs.ts";
|
||||
import { eitherValiParseCurried } from "./validation.ts";
|
||||
|
||||
export type GetLocalStorage<S extends GenericSchema> = Either<ErreursGetLocalStorage<S>, InferOutput<S>>;
|
||||
type ErreursGetLocalStorage<S extends GenericSchema> =
|
||||
| NonExistingKeyError
|
||||
| SyntaxError
|
||||
| ValiError<S>;
|
||||
|
||||
/**
|
||||
* Récupère une entrée dans le Stockage Local (`localStorage`) sous forme d'`Either`.
|
||||
*
|
||||
* @param cle La clé de l'entrée.
|
||||
* @returns Un `Either` avec une `NonExistingKeyError` si la clé est absente (`Left`), la
|
||||
* valeur de l'entrée sinon (`Right`).
|
||||
*/
|
||||
export const eitherGetLocalStorage = (cle: string): Either<NonExistingKeyError, string> =>
|
||||
Maybe
|
||||
.fromNullable(localStorage.getItem(cle))
|
||||
.toEither(ErreurEntreeInexistante(`Clé ${cle} absente dans le stockage de session.`));
|
||||
|
||||
export const getAndParseLocalStorage = <S extends GenericSchema>(cle: string, schema: S): GetLocalStorage<S> =>
|
||||
eitherGetLocalStorage(cle)
|
||||
.chain(eitherJsonParse)
|
||||
.chain(eitherValiParseCurried(schema));
|
||||
|
|
@ -14,7 +14,7 @@ import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER, TYPES_MESSAGES } fro
|
|||
import { reporteErreur } from "./erreurs.ts";
|
||||
import { WCErrorSchema } from "./schemas/api/erreurs.ts";
|
||||
import { MessageMajBoutonPanierSchema, MessageMajContenuPanierSchema } from "./schemas/messages.ts";
|
||||
import { eitherParse } from "./validation.ts";
|
||||
import { eitherValiParse } from "./validation.ts";
|
||||
|
||||
const canalPostMessage = (canal: BroadcastChannel, message: unknown): BroadcastChannel => {
|
||||
canal.postMessage(message);
|
||||
|
|
@ -78,6 +78,6 @@ export const valideMessageMajContenuPanier = (
|
|||
|
||||
// Correspondances
|
||||
export const reponseEstCodeErreurWC = (reponse: ReponseSimplifiee, codeErreurWC: string): boolean =>
|
||||
eitherParse(reponse, WCErrorSchema)
|
||||
eitherValiParse(reponse, WCErrorSchema)
|
||||
.map(v => v.body.code === codeErreurWC)
|
||||
.orDefault(false);
|
||||
|
|
|
|||
|
|
@ -14,5 +14,8 @@ export const inverseNombre = (nombre: number | string): number => Number(nombre)
|
|||
|
||||
export const formateEnEuros = (nombre: number | string): string => `${String(nombre)}€`;
|
||||
|
||||
export const diviseParCentEtFormateEnEuros = (nombre: number | string): string =>
|
||||
pipe(Number(nombre), diviseParCent, formateEnEuros);
|
||||
|
||||
export const diviseParCentEtArrondis = (nombre: number | string): string =>
|
||||
pipe(Number(nombre), diviseParCent, arrondisADeuxDecimales);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@
|
|||
import { Either } from "purify-ts";
|
||||
import { type GenericSchema, type InferOutput, parse, type ValiError } from "valibot";
|
||||
|
||||
export const eitherParse = <Schema extends GenericSchema>(
|
||||
export const eitherValiParse = <Schema extends GenericSchema>(
|
||||
valeur: unknown,
|
||||
schema: Schema,
|
||||
): Either<ValiError<Schema>, InferOutput<Schema>> => Either.encase(() => parse(schema, valeur));
|
||||
|
||||
export const eitherValiParseCurried =
|
||||
<S extends GenericSchema>(schema: S) => (valeur: unknown): Either<ValiError<S>, InferOutput<S>> =>
|
||||
Either.encase(() => parse(schema, valeur));
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { find as arrayFind, head as arrayHead } from "@mobily/ts-belt/Array";
|
|||
import { get as dictGet, map as dictMap, values as dictValues } from "@mobily/ts-belt/Dict";
|
||||
import { flatMap as optionFlatMap, getWithDefault as optionGetWithDefault } from "@mobily/ts-belt/Option";
|
||||
import { trim as stringTrim } from "@mobily/ts-belt/String";
|
||||
import { Option } from "@swan-io/boxed";
|
||||
import { EitherAsync, Maybe } from "purify-ts";
|
||||
import { match, P } from "ts-pattern";
|
||||
import { type AnySchema, ValiError } from "valibot";
|
||||
|
|
@ -21,13 +20,16 @@ import {
|
|||
ATTRIBUT_LIVRAISON_VALIDEE,
|
||||
SELECTEUR_BOUTON_ACTIONS_FORMULAIRE,
|
||||
SELECTEUR_BOUTON_SEPARATION_ADRESSES,
|
||||
SELECTEUR_CONTENEUR_METHODES_LIVRAISON,
|
||||
SELECTEUR_ENTREES_PANIER,
|
||||
SELECTEUR_FORMULAIRE_PANIER,
|
||||
SELECTEUR_INSTRUCTIONS_CLIENT,
|
||||
SELECTEUR_MESSAGE_FORMULAIRE_ADRESSES,
|
||||
SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT,
|
||||
SELECTEUR_SOUS_TOTAL_LIVRAISON_PRESTATAIRE,
|
||||
SELECTEUR_SOUS_TOTAL_PRODUITS,
|
||||
SELECTEUR_TOTAL_PANIER,
|
||||
} from "../constantes/dom";
|
||||
import { ADRESSES_MAJ, CODE_PROMO_MAJ } from "../constantes/evenements";
|
||||
import { NOM_CANAL_REVALIDATION_LIVRAISON } from "../constantes/messages";
|
||||
import {
|
||||
ERREUR_ADRESSE_MAUVAIS_CODE_POSTAL,
|
||||
|
|
@ -38,6 +40,7 @@ import {
|
|||
import { eitherJsonParse, eitherSessionStorageGet } from "../lib/dom";
|
||||
import { leveErreur, type NonExistingKeyError, reporteErreur, reporteEtJournaliseErreur } from "../lib/erreurs";
|
||||
import { ErreurAdresseInvalide } from "../lib/erreurs/adresses";
|
||||
import { ADRESSES_MAJ_EVENT } from "../lib/evenements/panier";
|
||||
import { emetUniqueMessageBroadcastChannel } from "../lib/messages";
|
||||
import { diviseParCent, formateEnEuros } from "../lib/nombres";
|
||||
import { creeReponseSimplifiee, eitherAsyncFetch, postBackend, traiteErreursBackendWooCommerce } from "../lib/reseau";
|
||||
|
|
@ -53,7 +56,8 @@ import {
|
|||
recupereElementsDocumentEither,
|
||||
recupereEleOuLeve,
|
||||
} from "../lib/utils";
|
||||
import { eitherParse } from "../lib/validation";
|
||||
import { eitherValiParse } from "../lib/validation";
|
||||
import { genereHtmlMethodesLivraison } from "./scripts-page-panier-methodes-livraison";
|
||||
|
||||
// @ts-expect-error -- États injectés par le modèle PHP
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP
|
||||
|
|
@ -62,42 +66,54 @@ const ETATS_PAGE: EtatsPageGenerique = _etats;
|
|||
const E = {
|
||||
BOUTON_ACTIONS_FORMULAIRE: recupereEleOuLeve<HTMLButtonElement>(SELECTEUR_BOUTON_ACTIONS_FORMULAIRE),
|
||||
BOUTON_SEPARATION_ADRESSES: recupereEleOuLeve<HTMLInputElement>(SELECTEUR_BOUTON_SEPARATION_ADRESSES),
|
||||
CONTENEUR_METHODES_LIVRAISON: recupereEleOuLeve<HTMLFieldSetElement>(SELECTEUR_CONTENEUR_METHODES_LIVRAISON),
|
||||
ENTREES_PANIER_EITHER: recupereElementsDocumentEither<HTMLElement>(SELECTEUR_ENTREES_PANIER),
|
||||
FORMULAIRE_PANIER: recupereEleOuLeve<HTMLFormElement>(SELECTEUR_FORMULAIRE_PANIER),
|
||||
INSTRUCTIONS_CLIENT: recupereEleOuLeve<HTMLTextAreaElement>(SELECTEUR_INSTRUCTIONS_CLIENT),
|
||||
MESSAGE_ADRESSES: recupereEleOuLeve<HTMLParagraphElement>(SELECTEUR_MESSAGE_FORMULAIRE_ADRESSES),
|
||||
TOTAL_LIVRAISON_COUT: recupereEleOuLeve<HTMLElement>(SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT),
|
||||
TOTAL_LIVRAISON_PRESTATAIRE: recupereEleOuLeve<HTMLSpanElement>(SELECTEUR_SOUS_TOTAL_LIVRAISON_PRESTATAIRE),
|
||||
SOUS_TOTAL_LIVRAISON_COUT: recupereEleOuLeve<HTMLElement>(SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT),
|
||||
SOUS_TOTAL_PRODUITS: recupereEleOuLeve<HTMLElement>(SELECTEUR_SOUS_TOTAL_PRODUITS),
|
||||
TOTAL_PANIER: recupereEleOuLeve<HTMLSpanElement>(SELECTEUR_TOTAL_PANIER),
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise l'écoute sur le `BroadcastChannel` de revalidation de la livraison.
|
||||
*
|
||||
* Lorsqu'un Message est émis, force l'Utilisateur à réaliser une requête pour le recalcul de ses conditions de
|
||||
* livraison.
|
||||
* Réinitialise le bouton de soumission du Formulaire en revenant à l'étape de validation des adresses.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
export const initialiseCanalRevalidationLivraison = (): void => {
|
||||
new BroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON).addEventListener("message", (): void => {
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.removeAttribute(ATTRIBUT_LIVRAISON_VALIDEE);
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.textContent = "Calculate shipping";
|
||||
});
|
||||
export const reinitialiseValidationLivraison = (): void => {
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.removeAttribute(ATTRIBUT_LIVRAISON_VALIDEE);
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.textContent = "Calculate shipping";
|
||||
};
|
||||
|
||||
/**
|
||||
* Lorsque le Formulaire du Panier change (que l'Utilisateur a changé une valeur), demande une revalidation
|
||||
* de la livraison si elle a été précédemment validée.
|
||||
* Initialise les Émetteurs d'Événements sur divers parties du Panier.
|
||||
*
|
||||
* 1. Émet un Événement de mise à jour des Adresses quand le Formulaire est modifié (s'il est valide).
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
export const demandeRevalidationLivraisonAMajFormulaires = (): void =>
|
||||
export const initialiseEmetteursEvenementsFormulairePanier = (): void => {
|
||||
E.FORMULAIRE_PANIER.addEventListener("change", (): void => {
|
||||
Maybe
|
||||
.fromFalsy(E.FORMULAIRE_PANIER.checkValidity())
|
||||
.chainNullable((): boolean => E.BOUTON_ACTIONS_FORMULAIRE.hasAttribute(ATTRIBUT_LIVRAISON_VALIDEE))
|
||||
.ifJust((): void => emetUniqueMessageBroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON, true));
|
||||
.ifJust((): boolean => window.dispatchEvent(ADRESSES_MAJ_EVENT));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Souscris aux différents Événements liés aux Panier et déclenche différentes opérations en fonction de ces derniers.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
export const souscrisEvenementsPanier = (): void => {
|
||||
window.addEventListener(ADRESSES_MAJ, (): void => {
|
||||
reinitialiseValidationLivraison();
|
||||
});
|
||||
window.addEventListener(CODE_PROMO_MAJ, (): void => {
|
||||
reinitialiseValidationLivraison();
|
||||
});
|
||||
};
|
||||
|
||||
export const initialiseBoutonCalculLivraison = (): void => {
|
||||
// Déclenche la requête pour la soumission des adresses
|
||||
|
|
@ -106,7 +122,9 @@ export const initialiseBoutonCalculLivraison = (): void => {
|
|||
// Ne fais rien si le Formulaire n'est pas valide
|
||||
.fromFalsy(E.FORMULAIRE_PANIER.checkValidity())
|
||||
// Ne fais rien si la livraison a déjà été validée
|
||||
.chainNullable((): boolean => !E.BOUTON_ACTIONS_FORMULAIRE.hasAttribute(ATTRIBUT_LIVRAISON_VALIDEE))
|
||||
.chainNullable((): boolean | null =>
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.hasAttribute(ATTRIBUT_LIVRAISON_VALIDEE) ? null : true
|
||||
)
|
||||
.ifJust((): void => {
|
||||
evenement.preventDefault();
|
||||
|
||||
|
|
@ -151,7 +169,7 @@ export const initialiseBoutonCalculLivraison = (): void => {
|
|||
// Réalise la requête et traite sa réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse(argumentsFormulaire, WCStoreCartUpdateCustomerArgsSchema))
|
||||
.liftEither(eitherValiParse(argumentsFormulaire, WCStoreCartUpdateCustomerArgsSchema))
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes et lancer une animation de chargement
|
||||
.ifRight((): void => {
|
||||
// Désactive le Bouton pour empêcher des requêtes concurrentes
|
||||
|
|
@ -176,28 +194,29 @@ export const initialiseBoutonCalculLivraison = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherParse(corps, WCStoreCartSchema)))
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherValiParse(corps, WCStoreCartSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((panier: WCStoreCart): void => {
|
||||
E.MESSAGE_ADRESSES.textContent = " ";
|
||||
|
||||
const sousTotalLivraison = panier.totals.total_shipping === 0
|
||||
? "Free"
|
||||
: pipe(diviseParCent(panier.totals.total_shipping), formateEnEuros);
|
||||
// const sousTotalLivraison = panier.totals.total_shipping === 0
|
||||
// ? "Free"
|
||||
// : pipe(diviseParCent(panier.totals.total_shipping), formateEnEuros);
|
||||
const sousTotalLivraison = pipe(diviseParCent(panier.totals.total_shipping), formateEnEuros);
|
||||
const methodesLivraison = pipe(arrayHead(panier.shipping_rates), optionFlatMap(dictGet("shipping_rates")));
|
||||
const methodeChoisie = optionFlatMap(methodesLivraison, arrayHead);
|
||||
const prestataireLivraison = pipe(methodeChoisie, optionFlatMap(dictGet("name")));
|
||||
|
||||
// Met à jour les informations de Livraison affichés à l'Utilisateur
|
||||
E.TOTAL_LIVRAISON_COUT.textContent = sousTotalLivraison;
|
||||
E.TOTAL_LIVRAISON_PRESTATAIRE.textContent = optionGetWithDefault(prestataireLivraison, "???");
|
||||
E.SOUS_TOTAL_LIVRAISON_COUT.textContent = sousTotalLivraison;
|
||||
|
||||
// Sauvegarde la Méthode de Livraison dans le Stockage de Session
|
||||
sessionStorage.setItem(
|
||||
// Sauvegarde la Méthode de Livraison dans LocalStorage
|
||||
localStorage.setItem(
|
||||
"shipping_rates",
|
||||
JSON.stringify(optionGetWithDefault(methodesLivraison, [])),
|
||||
);
|
||||
|
||||
// Affiche les méthodes disponibles à l'Utilisateur
|
||||
genereHtmlMethodesLivraison(E.CONTENEUR_METHODES_LIVRAISON, optionGetWithDefault(methodesLivraison, []));
|
||||
|
||||
// Active le Bouton pour la création de la Commande
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.textContent = "Check-out";
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.setAttribute(ATTRIBUT_LIVRAISON_VALIDEE, "");
|
||||
|
|
@ -277,7 +296,7 @@ export const initialiseBoutonCreationCommande = (): void => {
|
|||
// Récupère la méthode de livraison depuis le stockage de session sous forme d'objet
|
||||
.chain(eitherJsonParse)
|
||||
// Vérifie la forme de l'objet récupéré
|
||||
.chain((json: JSONValue) => eitherParse(json, WCStoreShippingRateShippingRatesSchema))
|
||||
.chain((json: JSONValue) => eitherValiParse(json, WCStoreShippingRateShippingRatesSchema))
|
||||
// Traite de manière différenciée les Erreurs
|
||||
.ifLeft((erreur: NonExistingKeyError | SyntaxError | ValiError<AnySchema>): void => {
|
||||
match(erreur)
|
||||
|
|
@ -356,7 +375,7 @@ export const initialiseBoutonCreationCommande = (): void => {
|
|||
// Réalise la requête et traite sa réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse(argumentsFormulaire, WCV3OrdersArgsSchema))
|
||||
.liftEither(eitherValiParse(argumentsFormulaire, WCV3OrdersArgsSchema))
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes et lancer une animation de chargement
|
||||
.ifRight((): void => {
|
||||
// Désactive le Bouton pour empêcher des requêtes concurrentes
|
||||
|
|
@ -382,7 +401,7 @@ export const initialiseBoutonCreationCommande = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherParse(corps, WCV3OrderSchema)))
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherValiParse(corps, WCV3OrderSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((commande: WCV3Order): void => {
|
||||
E.BOUTON_ACTIONS_FORMULAIRE.removeAttribute(ATTRIBUT_CHARGEMENT);
|
||||
|
|
@ -390,11 +409,11 @@ export const initialiseBoutonCreationCommande = (): void => {
|
|||
E.MESSAGE_ADRESSES.textContent = " ";
|
||||
|
||||
// Redirige vers Stripe
|
||||
Option
|
||||
Maybe
|
||||
.fromNullable(new URL(`https://${window.location.host}/checkout`))
|
||||
.tapSome(url => url.searchParams.append("order_key", commande.order_key))
|
||||
.tapSome(url => url.searchParams.append("order_id", String(commande.id)))
|
||||
.tapSome(url => location.assign(url));
|
||||
.ifJust(url => url.searchParams.append("order_key", commande.order_key))
|
||||
.ifJust(url => url.searchParams.append("order_id", String(commande.id)))
|
||||
.ifJust(url => location.assign(url));
|
||||
})
|
||||
// 7. Traite les Erreurs et affiche un message à l'Utilisateur
|
||||
.ifLeft((erreur: FetchErrors | HttpCodeErrors | ValiError<AnySchema>): void => {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import { lanceAnimationCycleLoading } from "../lib/animations";
|
|||
import { accorderCibleASelecteur } from "../lib/dom";
|
||||
import { reporteErreur, ServerError } from "../lib/erreurs";
|
||||
import { ErreurCodePromoInvalide } from "../lib/erreurs/codes-promo";
|
||||
import { CODE_PROMO_MAJ_EVENT } from "../lib/evenements/panier";
|
||||
import { estReponse500 } from "../lib/gardes";
|
||||
import { emetUniqueMessageBroadcastChannel, reponseEstCodeErreurWC } from "../lib/messages";
|
||||
import { arrondisADeuxDecimales, diviseParCent, formateEnEuros, inverseNombre } from "../lib/nombres";
|
||||
|
|
@ -41,7 +42,7 @@ import { WCStoreCartSchema } from "../lib/schemas/api/cart";
|
|||
import { WCStoreCartApplyCouponArgsSchema } from "../lib/schemas/api/cart-apply-coupon";
|
||||
import { WCStoreCartRemoveCouponArgsSchema } from "../lib/schemas/api/cart-remove-coupon";
|
||||
import { recupereEleOuLeve } from "../lib/utils";
|
||||
import { eitherParse } from "../lib/validation";
|
||||
import { eitherValiParse } from "../lib/validation";
|
||||
|
||||
// @ts-expect-error -- États injectés par le modèle PHP
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP
|
||||
|
|
@ -82,7 +83,7 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
({ valeurCodePromo }) =>
|
||||
void EitherAsync
|
||||
// Vérifie le Schéma des arguments
|
||||
.liftEither(eitherParse({ code: valeurCodePromo }, WCStoreCartApplyCouponArgsSchema))
|
||||
.liftEither(eitherValiParse({ code: valeurCodePromo }, WCStoreCartApplyCouponArgsSchema))
|
||||
.ifRight(() => {
|
||||
// Désactive le Bouton pour empêcher des requêtes concurrentes
|
||||
E.BOUTON_CODE_PROMO.setAttribute(ATTRIBUT_DESACTIVE, "");
|
||||
|
|
@ -120,7 +121,7 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
})
|
||||
)
|
||||
// Vérifie le Schéma de la Réponse du backend
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherParse(corpsReponse, WCStoreCartSchema)))
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherValiParse(corpsReponse, WCStoreCartSchema)))
|
||||
// Déclenche les mises à jour du DOM avec les données du nouveau Panier
|
||||
.ifRight((panier: WCStoreCart) => {
|
||||
E.ENSEMBLE_CODE_PROMO.toggleAttribute(ATTRIBUT_CODE_PROMO_PRESENT);
|
||||
|
|
@ -141,7 +142,8 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
formateEnEuros,
|
||||
);
|
||||
|
||||
emetUniqueMessageBroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON, true);
|
||||
window.dispatchEvent(CODE_PROMO_MAJ_EVENT);
|
||||
// emetUniqueMessageBroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON, true);
|
||||
})
|
||||
.ifLeft(erreur => {
|
||||
// Rétablis le texte d'origine
|
||||
|
|
@ -174,6 +176,7 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
})
|
||||
.finally(() => {
|
||||
// Désactive l'animation de chargement et rend le Bouton de nouveau cliquable
|
||||
// TODO: Créer un type d'Événement ?
|
||||
E.BOUTON_CODE_PROMO.removeAttribute(ATTRIBUT_CHARGEMENT);
|
||||
E.BOUTON_CODE_PROMO.removeAttribute(ATTRIBUT_DESACTIVE);
|
||||
})
|
||||
|
|
@ -189,7 +192,7 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
},
|
||||
({ valeurCodePromo }) =>
|
||||
void EitherAsync
|
||||
.liftEither(eitherParse({ code: valeurCodePromo }, WCStoreCartRemoveCouponArgsSchema))
|
||||
.liftEither(eitherValiParse({ code: valeurCodePromo }, WCStoreCartRemoveCouponArgsSchema))
|
||||
.ifRight(() => {
|
||||
E.BOUTON_CODE_PROMO.setAttribute(ATTRIBUT_DESACTIVE, "");
|
||||
E.BOUTON_CODE_PROMO.setAttribute(ATTRIBUT_CHARGEMENT, "");
|
||||
|
|
@ -209,7 +212,7 @@ export const initialiseElementsCodePromo = (): void => {
|
|||
return await reponse.json();
|
||||
})
|
||||
)
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherParse(corpsReponse, WCStoreCartSchema)))
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherValiParse(corpsReponse, WCStoreCartSchema)))
|
||||
.ifRight((panier: WCStoreCart) => {
|
||||
E.ENSEMBLE_CODE_PROMO.toggleAttribute(ATTRIBUT_CODE_PROMO_PRESENT);
|
||||
E.ENSEMBLE_CODE_PROMO.reset();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
import { find as arrayFind, forEach as arrayForEach, map as arrayMap } from "@mobily/ts-belt/Array";
|
||||
import { html, render, type TemplateResult } from "lit-html";
|
||||
import { Maybe } from "purify-ts";
|
||||
|
||||
import type { WCStoreShippingRateShippingRate } from "../lib/types/api/cart";
|
||||
import type { WCStoreShippingRateShippingRates } from "../lib/types/api/couts-livraison";
|
||||
|
||||
import {
|
||||
ATTRIBUT_HIDDEN,
|
||||
SELECTEUR_CONTENEUR_METHODES_LIVRAISON,
|
||||
SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT,
|
||||
SELECTEUR_SOUS_TOTAL_PRODUITS,
|
||||
SELECTEUR_TOTAL_PANIER,
|
||||
} from "../constantes/dom";
|
||||
import { recupereElementsAvecSelecteur } from "../lib/dom";
|
||||
import { reporteEtJournaliseErreur } from "../lib/erreurs";
|
||||
import { getAndParseLocalStorage } from "../lib/local-storage";
|
||||
import { diviseParCent, diviseParCentEtFormateEnEuros, formateEnEuros } from "../lib/nombres";
|
||||
import { WCStoreShippingRateShippingRatesSchema } from "../lib/schemas/api/couts-livraison";
|
||||
import { recupereEleOuLeve } from "../lib/utils";
|
||||
|
||||
const E = {
|
||||
CONTENEUR_METHODES_LIVRAISON: recupereEleOuLeve<HTMLFieldSetElement>(SELECTEUR_CONTENEUR_METHODES_LIVRAISON),
|
||||
SOUS_TOTAL_LIVRAISON_COUT: recupereEleOuLeve<HTMLElement>(SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT),
|
||||
SOUS_TOTAL_PRODUITS: recupereEleOuLeve<HTMLElement>(SELECTEUR_SOUS_TOTAL_PRODUITS),
|
||||
TOTAL_PANIER: recupereEleOuLeve<HTMLSpanElement>(SELECTEUR_TOTAL_PANIER),
|
||||
};
|
||||
|
||||
/**
|
||||
* Créé un Événement MethodesLivraisonMaj déclenché quand l'Utilisateur change son choix avec en corps un object ShippingRates
|
||||
* À l'Émission, sauvegarde les méthodes mises à jour dans le LocalStorage et met à jour le DOM
|
||||
* Le déclenchement de la mise à jour des adresses déclenche aussi cet Événement.
|
||||
* Le LocalStorage est comparé avec la Réponse, et si la méthode jusqe-là sélectionnée est présente dans la Réponse, la mise à jour du DOM doit se faire en conservant ce choix.
|
||||
*/
|
||||
|
||||
export const initialiseBoutonsChoixMethodesLivraison = (): void => {
|
||||
recupereElementsAvecSelecteur(E.CONTENEUR_METHODES_LIVRAISON)<HTMLInputElement>("input").ifRight(
|
||||
arrayForEach((i): void =>
|
||||
// Met à jour sous-total de livraison et total au changement de méthode
|
||||
i.addEventListener("click", (evenement: MouseEvent): void => {
|
||||
const methodeChoisie = (evenement.target as HTMLInputElement).value;
|
||||
|
||||
getAndParseLocalStorage("shipping_rates", WCStoreShippingRateShippingRatesSchema)
|
||||
.map(arrayMap((m): WCStoreShippingRateShippingRate => {
|
||||
m.selected = m.method_id === methodeChoisie;
|
||||
return m;
|
||||
}))
|
||||
// Enregistre les méthodes de livraison mises à jour
|
||||
.ifRight((xs): void => localStorage.setItem("shipping_rates", JSON.stringify(xs)))
|
||||
.ifLeft(reporteEtJournaliseErreur)
|
||||
// Met à jour sous-total livraison et total
|
||||
.toMaybe()
|
||||
.chainNullable(xs => xs.find(m => m.selected))
|
||||
.ifJust((m): void => {
|
||||
Maybe
|
||||
.fromNullable(E.SOUS_TOTAL_PRODUITS.textContent)
|
||||
.map(s => s.split("€")[0])
|
||||
.chainNullable(Number)
|
||||
.map(t => formateEnEuros(t + diviseParCent(m.price)))
|
||||
.ifJust(t => {
|
||||
E.TOTAL_PANIER.textContent = t;
|
||||
E.SOUS_TOTAL_LIVRAISON_COUT.textContent = diviseParCentEtFormateEnEuros(m.price);
|
||||
});
|
||||
});
|
||||
})
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
export const genereHtmlMethodesLivraison = (
|
||||
conteneur: HTMLElement,
|
||||
methodes: WCStoreShippingRateShippingRates,
|
||||
): void => {
|
||||
// Cache les méthodes s'il n'y en a pas
|
||||
if (methodes.length === 0) {
|
||||
conteneur.setAttribute(ATTRIBUT_HIDDEN, "");
|
||||
return;
|
||||
}
|
||||
|
||||
// Retire les méthodes de livraison initiales
|
||||
recupereElementsAvecSelecteur(conteneur)("div[data-methode-initiale]").ifRight(arrayForEach(div => div.remove()));
|
||||
|
||||
const methodeSelectionnee: string = getAndParseLocalStorage("shipping_rates", WCStoreShippingRateShippingRatesSchema)
|
||||
.ifLeft(reporteEtJournaliseErreur)
|
||||
.toMaybe()
|
||||
.chainNullable(arrayFind(m => m.selected))
|
||||
.map(m => m.method_id)
|
||||
.orDefault("");
|
||||
|
||||
const methodesHtml: ReadonlyArray<TemplateResult> = arrayMap(methodes, methode => {
|
||||
return html`
|
||||
<div>
|
||||
<input
|
||||
id="methode-livraison-${methode.method_id}"
|
||||
name="choix-methode-livraison"
|
||||
type="radio"
|
||||
value="${methode.method_id}"
|
||||
.checked="${methode.method_id === methodeSelectionnee}"
|
||||
>
|
||||
<label for="methode-livraison-${methode.method_id}">${methode.name} (${
|
||||
diviseParCentEtFormateEnEuros(methode.price)
|
||||
})</label>
|
||||
</div>`;
|
||||
});
|
||||
|
||||
// Ajoute les nouveaux Produits dans le DOM
|
||||
conteneur.removeAttribute(ATTRIBUT_HIDDEN);
|
||||
render(methodesHtml, conteneur);
|
||||
// Recréé les Écouteurs de clic sur les choix de méthodes
|
||||
initialiseBoutonsChoixMethodesLivraison();
|
||||
};
|
||||
|
|
@ -37,7 +37,7 @@ import { WCStoreCartSchema } from "../lib/schemas/api/cart";
|
|||
import { WCStoreCartRemoveItemArgsSchema } from "../lib/schemas/api/cart-remove-item";
|
||||
import { WCStoreCartUpdateItemArgsSchema } from "../lib/schemas/api/cart-update-item";
|
||||
import { recupereElementsDocumentEither } from "../lib/utils";
|
||||
import { eitherParse } from "../lib/validation";
|
||||
import { eitherValiParse } from "../lib/validation";
|
||||
|
||||
// @ts-expect-error -- États injectés par le modèle PHP
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP
|
||||
|
|
@ -122,7 +122,9 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
// Réalise la requête et traite sa réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse({ key: clePanier, quantity: valeur + 1 }, WCStoreCartUpdateItemArgsSchema))
|
||||
.liftEither(
|
||||
eitherValiParse({ key: clePanier, quantity: valeur + 1 }, WCStoreCartUpdateItemArgsSchema),
|
||||
)
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes
|
||||
.ifRight(() => pipe(entrees, arrayMap(recupereElementsEntreePanier), majActivationBoutons(false)))
|
||||
// 3. Exécute la requête via fetch sous forme d'EitherAsync
|
||||
|
|
@ -145,7 +147,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherParse(corps, WCStoreCartSchema)))
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherValiParse(corps, WCStoreCartSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((panier: WCStoreCart): void => {
|
||||
// Émet un Message avec le nouveau nombre de Produits dans le Panier
|
||||
|
|
@ -202,7 +204,9 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
// Réalise la requête et traite sa réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse({ key: clePanier, quantity: valeur - 1 }, WCStoreCartUpdateItemArgsSchema))
|
||||
.liftEither(
|
||||
eitherValiParse({ key: clePanier, quantity: valeur - 1 }, WCStoreCartUpdateItemArgsSchema),
|
||||
)
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes
|
||||
.ifRight(() => pipe(entrees, arrayMap(recupereElementsEntreePanier), majActivationBoutons(false)))
|
||||
// 3. Exécute la requête via fetch sous forme d'EitherAsync
|
||||
|
|
@ -225,7 +229,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherParse(corps, WCStoreCartSchema)))
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherValiParse(corps, WCStoreCartSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((panier: WCStoreCart): void => {
|
||||
// Émet un Message avec le nouveau nombre de Produits dans le Panier
|
||||
|
|
@ -281,7 +285,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
// Réalise la requête et traite sa réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse({ key: clePanier }, WCStoreCartRemoveItemArgsSchema))
|
||||
.liftEither(eitherValiParse({ key: clePanier }, WCStoreCartRemoveItemArgsSchema))
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes
|
||||
.ifRight(() => pipe(entrees, arrayMap(recupereElementsEntreePanier), majActivationBoutons(false)))
|
||||
// 3. Exécute la requête via fetch sous forme d'EitherAsync
|
||||
|
|
@ -304,7 +308,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherParse(corps, WCStoreCartSchema)))
|
||||
.chain((corps: unknown) => EitherAsync.liftEither(eitherValiParse(corps, WCStoreCartSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((panier: WCStoreCart): void => {
|
||||
// Émet un Message avec le nouveau nombre de Produits dans le Panier
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import { BadRequestError, reporteErreur, ServerError } from "./lib/erreurs.ts";
|
|||
import { creeReponseSimplifiee, getBackendAvecParametresUrl } from "./lib/reseau.ts";
|
||||
import { WCV3ProductsArgsSchema, WCV3ProductsSchema } from "./lib/schemas/api/v3/products.ts";
|
||||
import { recupereEleOuLeve } from "./lib/utils.ts";
|
||||
import { eitherParse } from "./lib/validation.ts";
|
||||
import { eitherValiParse } from "./lib/validation.ts";
|
||||
|
||||
// @ts-expect-error -- États injectés par le modèle PHP
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP
|
||||
|
|
@ -62,7 +62,7 @@ const initialisePageBoutique = (): void => {
|
|||
|
||||
void EitherAsync
|
||||
// 1. Valide les Arguments de la Requête
|
||||
.liftEither(eitherParse(args, WCV3ProductsArgsSchema))
|
||||
.liftEither(eitherValiParse(args, WCV3ProductsArgsSchema))
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes et lancer une animation de chargement
|
||||
.ifRight(() => {
|
||||
// Désactive le Bouton pour empêcher des requêtes concurrentes
|
||||
|
|
@ -94,7 +94,7 @@ const initialisePageBoutique = (): void => {
|
|||
})
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherParse(corpsReponse, WCV3ProductsSchema)))
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherValiParse(corpsReponse, WCV3ProductsSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((donnees: WCV3Products) => {
|
||||
// Cache le bouton s'il y a moins de 12 Produits disponibles (que l'on est à la dernière page)
|
||||
|
|
|
|||
|
|
@ -33,12 +33,13 @@ import { valideMessageMajBoutonPanier, valideMessageMajContenuPanier } from "./l
|
|||
import { arrondisADeuxDecimales, diviseParCent, formateEnEuros, inverseNombre } from "./lib/nombres.ts";
|
||||
import { propEither, recupereElementsDocumentEither, recupereEleOuLeve } from "./lib/utils.ts";
|
||||
import {
|
||||
demandeRevalidationLivraisonAMajFormulaires,
|
||||
initialiseBoutonCalculLivraison,
|
||||
initialiseBoutonCreationCommande,
|
||||
initialiseCanalRevalidationLivraison,
|
||||
initialiseEmetteursEvenementsFormulairePanier,
|
||||
souscrisEvenementsPanier,
|
||||
} from "./page-panier/scripts-page-panier-adresses.ts";
|
||||
import { initialiseElementsCodePromo } from "./page-panier/scripts-page-panier-code-promo.ts";
|
||||
import { initialiseBoutonsChoixMethodesLivraison } from "./page-panier/scripts-page-panier-methodes-livraison.ts";
|
||||
import { initialiseActionsEntreesPanier } from "./page-panier/scripts-page-panier-panneau-produits.ts";
|
||||
|
||||
type ElementsEntreePanier = {
|
||||
|
|
@ -193,13 +194,14 @@ const initialiseMajFormulairesPanier = (): void => {
|
|||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", (): void => {
|
||||
initialiseCanalRevalidationLivraison();
|
||||
initialiseEmetteursEvenementsFormulairePanier();
|
||||
souscrisEvenementsPanier();
|
||||
initialiseActionsEntreesPanier();
|
||||
initialiseBoutonsChoixMethodesLivraison();
|
||||
initialiseMajConteneurPanier();
|
||||
initialiseMajContenuPanier();
|
||||
initialiseMajFormulairesPanier();
|
||||
initialiseBoutonCalculLivraison();
|
||||
initialiseBoutonCreationCommande();
|
||||
initialiseElementsCodePromo();
|
||||
demandeRevalidationLivraisonAMajFormulaires();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import { creeReponseSimplifiee, eitherAsyncFetch, postBackend } from "./lib/rese
|
|||
import { WCStoreCartAddItemArgsSchema } from "./lib/schemas/api/cart-add-item.ts";
|
||||
import { WCStoreCartSchema } from "./lib/schemas/api/cart.ts";
|
||||
import { recupereElementDocumentEither, recupereEleOuLeve, recupereElesOuLeve } from "./lib/utils.ts";
|
||||
import { eitherParse } from "./lib/validation.ts";
|
||||
import { eitherValiParse } from "./lib/validation.ts";
|
||||
|
||||
type EnsembleLienContenu = [HTMLAnchorElement, HTMLElement];
|
||||
/** États utiles pour les scripts de la page. */
|
||||
|
|
@ -201,7 +201,7 @@ const ajouteProduitAuPanier = (): void => {
|
|||
// Réalise la Requête et traite sa Réponse
|
||||
void EitherAsync
|
||||
// 1. Valide les arguments de la Requête
|
||||
.liftEither(eitherParse(argsRequete, WCStoreCartAddItemArgsSchema))
|
||||
.liftEither(eitherValiParse(argsRequete, WCStoreCartAddItemArgsSchema))
|
||||
// 2. Exécute un Effet pour empêcher les requêtes concurrentes et lancer une animation de chargement
|
||||
.ifRight(() => {
|
||||
// Désactive le Bouton pour empêcher des requêtes concurrentes
|
||||
|
|
@ -233,7 +233,7 @@ const ajouteProduitAuPanier = (): void => {
|
|||
)
|
||||
)
|
||||
// 5. Vérifie le Schéma de la Réponse
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherParse(corpsReponse, WCStoreCartSchema)))
|
||||
.chain((corpsReponse: unknown) => EitherAsync.liftEither(eitherValiParse(corpsReponse, WCStoreCartSchema)))
|
||||
// 6. Exécute un Effet pour la mise à jour du DOM avec les Résultats
|
||||
.ifRight((panier: WCStoreCart) =>
|
||||
pipe(
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
<div class="detail-produit__actions">
|
||||
<button
|
||||
class="detail-produit__actions__soustraction"
|
||||
{{ produit.quantite > 1 ? "" : "disabled" }}
|
||||
{{ produit.quantite < 1 ? "disabled" }}
|
||||
type="button"
|
||||
>
|
||||
-
|
||||
|
|
@ -85,18 +85,18 @@
|
|||
<form
|
||||
action=""
|
||||
class="panneau__instructions-code-promo__code-promo"
|
||||
{{ code_promo ? "data-code-promo-present" : "" }}
|
||||
{{ code_promo ? "data-code-promo-present" }}
|
||||
id="ensemble-code-promo"
|
||||
>
|
||||
<input
|
||||
{{ code_promo ? "disabled" : "" }}
|
||||
{{ code_promo ? "disabled" }}
|
||||
id="champ-code-promo"
|
||||
maxlength="20"
|
||||
minlength="3"
|
||||
name="code-promo"
|
||||
placeholder="Discount code or gift card"
|
||||
type="text"
|
||||
value='{{ code_promo ? code_promo : ""}}'
|
||||
value="{{ code_promo ? code_promo }}"
|
||||
>
|
||||
<button
|
||||
class="bouton-blanc-sur-noir"
|
||||
|
|
@ -123,7 +123,7 @@
|
|||
<div
|
||||
class="panneau__sous-totaux__ligne"
|
||||
id="sous-total-reduction"
|
||||
{{ code_promo ? "" : "hidden"}}
|
||||
{{ not code_promo ? "hidden"}}
|
||||
>
|
||||
<p>Discount:</p>
|
||||
<p><strong>-{{ sous_total_reduction }}€</strong></p>
|
||||
|
|
@ -134,23 +134,43 @@
|
|||
id="sous-total-livraison"
|
||||
>
|
||||
<p>Shipping:</p>
|
||||
{% if sous_total_livraison == 0 %}
|
||||
{% if not adresse_renseignee %}
|
||||
<p>
|
||||
<strong>Enter your delivery address</strong>
|
||||
<br>
|
||||
<span> </span>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
<strong>{{ sous_total_livraison }}€</strong>
|
||||
<br>
|
||||
<span>{{ methode_livraison }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<fieldset
|
||||
class="panneau__sous-totaux__choix-methode-livraison"
|
||||
{{ not adresse_renseignee ? "hidden" }}
|
||||
id="choix-methode-livraison"
|
||||
>
|
||||
<label>Select your shipping method</label>
|
||||
|
||||
{% for methode_livraison in methodes_livraison %}
|
||||
<div data-methode-initiale>
|
||||
<input
|
||||
{{ methode_livraison.selectionnee ? "checked"}}
|
||||
data-prix="{{ methode_livraison.prix }}"
|
||||
id="methode-livraison-{{ methode_livraison.id }}"
|
||||
name="choix-methode-livraison"
|
||||
type="radio"
|
||||
value="{{ methode_livraison.id }}"
|
||||
>
|
||||
<label for="methode-livraison-{{ methode_livraison.id }}">{{ methode_livraison.titre }} ({{
|
||||
methode_livraison.prix
|
||||
}}€)</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
|
||||
<p class="panneau__sous-totaux__conditions-livraison">
|
||||
Belgium and France: free shipping on orders above 50€.<br>
|
||||
Belgium and France: free shipping on orders above 50€ (Pickup Point only).<br>
|
||||
Worldwide: free shipping on orders above 100€.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue