2026-04-07

This commit is contained in:
gcch 2026-04-07 11:06:38 +02:00
commit c255798aab
8 changed files with 88 additions and 98 deletions

View file

@ -19,7 +19,7 @@ $templates = ['contact.twig'];
add_action('wp_enqueue_scripts', function (): void {
Resource::enqueue_style_file(
handle: 'haiku-atelier-2024-styles-page-contact',
path: '/assets/css/pages/page-contact.css',
path: '/assets/css/pages/page-contact.min.css',
);
});

View file

@ -65,12 +65,12 @@ $product_tags = $raw_product->get_tag_ids()
|> (static fn(/** @var list<Option<WC_Term>> */ $tags) => Arr::map($tags, static fn($tag) => $tag->unwrap()));
$tags = get_terms(['taxonomy' => 'product_tag', 'hide_empty' => true]);
echo '<pre>';
print_r($product_tags);
print_r($tags);
echo '</pre>';
// echo '<pre>';
// print_r($product_tags);
// print_r($tags);
// echo '</pre>';
exit();
// exit();
add_action('wp_enqueue_scripts', function (): void {
Resource::enqueue_script_module_file(

View file

@ -26,7 +26,8 @@ final readonly class Attribute {
/** @var list<WP_Term> */
$terms = $attribute->get_terms() ?? [];
/** @var list<AttributeOption> */
$options = Arr::map($terms, AttributeOption::new(...));
$options = Arr::map($terms, AttributeOption::new(...))
|> (static fn($options) => Arr::sort($options, static fn($attribute) => $attribute->id));
return new self(name: $name, slug: $slug, options: $options);
}

View file

@ -4,7 +4,7 @@ import { pipe } from "@mobily/ts-belt";
import { forEach as arrayForEach } from "@mobily/ts-belt/Array";
import { get as dictGet } from "@mobily/ts-belt/Dict";
import { tap as optionTap } from "@mobily/ts-belt/Option";
import { pipe as epipe } from "effect";
import { Array as FxArray, Effect, pipe as epipe, Option, Stream } from "effect";
import { EitherAsync, Maybe } from "purify-ts";
import { match, P } from "ts-pattern";
import { ValiError } from "valibot";
@ -37,6 +37,7 @@ import { newPartialResponse, postBackend, safeFetch } from "./lib/reseau.ts";
import { WCStoreCartAddItemArgsSchema } from "./lib/schemas/api/cart-add-item.ts";
import { WCStoreCartSchema } from "./lib/schemas/api/cart.ts";
import { safeSchemaParse } from "./lib/validation";
import { getAllSelectorFromDocument } from "../scripts-effect/lib/dom.ts";
type EnsembleLienContenu = [HTMLAnchorElement, HTMLElement];
@ -72,6 +73,7 @@ const E = {
VARIATION_CHOICE_FORM: mustGetEleInDocument<HTMLFormElement>("#variation-choice"),
};
// TODO: Moderniser.
const gereAccordeonDetailsProduit = (): void => {
const contenus = new Map<string, EnsembleLienContenu>();
@ -132,6 +134,7 @@ const gereAccordeonDetailsProduit = (): void => {
E.BOUTON_AJOUT_PANIER.addEventListener("click", (event: MouseEvent): void => ajouteProduitAuPanier(event));
};
// TODO: Utiliser Effect.
const getAttributesFromDom = (): ReadonlyArray<WCStoreCartAddItemArgsItems> => {
const selectElements = epipe(
document.querySelectorAll<HTMLSelectElement>(".selecteur-produit select"),
@ -262,40 +265,47 @@ const ajouteProduitAuPanier = (event: MouseEvent): void => {
.run();
};
const initAddToCartButtonActivationOnUserChoice = (): void => {
const isInStock = E.BOUTON_AJOUT_PANIER.hasAttribute("data-in-stock");
const initAddToCartButton = Effect.fn("initAddToCartButton")(function* () {
/** Est-ce que le Produit affiché est en stock ? */
const isProductInStock = E.BOUTON_AJOUT_PANIER.hasAttribute("data-in-stock");
// S'il n'y a pas de stock, ne rien faire.
if (!isInStock) {
return;
if (isProductInStock === false) {
console.debug("initAddToCartButton", "Pas de stock.");
return yield* Effect.void;
}
// S'il n'y a pas de sélecteur de variation, activer le bouton.
const selectElements: ReadonlyArray<HTMLSelectElement> = epipe(
document.querySelectorAll<HTMLSelectElement>(".selecteur-produit select"),
Array.from<HTMLSelectElement>,
);
if (selectElements.length === 0) {
const variationSelectors = getAllSelectorFromDocument<HTMLSelectElement>(".selecteur-produit select");
// S'il n'y a pas de Sélecteurs de variations, activer le Bouton d'ajout au Panier.
if (Option.isNone(variationSelectors)) {
E.BOUTON_AJOUT_PANIER.removeAttribute(ATTRIBUT_DESACTIVE);
}
// (Dés)active le bouton d'ajout au panier en fonction de la validité du formulaire.
E.VARIATION_CHOICE_FORM.addEventListener("change", (): void => {
const isFormValid = E.VARIATION_CHOICE_FORM.checkValidity();
return yield* Effect.void;
});
if (isFormValid) {
E.BOUTON_AJOUT_PANIER.removeAttribute(ATTRIBUT_DESACTIVE);
} else {
E.BOUTON_AJOUT_PANIER.setAttribute(ATTRIBUT_DESACTIVE, "");
}
});
};
const initAddToCartInteractionUpdates = Effect.fn("initAddToCartInteractionUpdates")(function* () {
return yield* pipe(
Stream.fromEventListener(E.VARIATION_CHOICE_FORM, "change"),
Stream.tap((event: Event) => {
console.debug("initAddToCartInteractionUpdates", "hello");
// La cible ne peut qu'être un Formulaire.
const target = event.target as HTMLFormElement;
const isClickAllowed = target.checkValidity() === false;
// Active/désactive le Bouton en fonction de la validité du Formulaire du Produit.
E.BOUTON_AJOUT_PANIER.toggleAttribute(ATTRIBUT_DESACTIVE, isClickAllowed);
return Effect.void;
}),
Stream.runDrain,
);
});
document.addEventListener("DOMContentLoaded", (): void => {
gereAccordeonDetailsProduit();
initAddToCartButtonActivationOnUserChoice();
Effect.runFork(initAddToCartButton());
Effect.runFork(initAddToCartInteractionUpdates());
updatePriceOnAttributeChange();
// DEBUG
console.debug(JSON.parse(document.querySelector("#product-json")?.textContent));
});

View file

@ -19,41 +19,6 @@
</div>
{% endfor %}
{% endif %}
{#
{% if variations_produit|length > 1 %}
<label
for="selecteur-variation"
id="label-selecteur-variation"
>
Option:
</label>
<div class="selecteur-produit__attribut-variation__selecteurs">
<select
aria-labelledby="label-selecteur-variation"
id="selecteur-variation"
name="variations"
>
<option
disabled
selected
value=""
>
--
</option>
{% for variation in variations_produit %}
<option
data-prix="{{ variation.prix }}"
value="{{ variation.id }}"
>
{{ variation.titre }}
</option>
{% endfor %}
</select>
</div>
{% endif %}
#}
</div>
<p class="selecteur-produit__prix">{{ maximum_price ?? product.price }}€</p>