Add nice snackbar message on counter interface and fix not enough money protection on frontend

This commit is contained in:
Antoine Bartuccio 2024-12-23 00:56:57 +01:00
parent b8d43a629b
commit 472800eff6
2 changed files with 52 additions and 14 deletions

View File

@ -9,6 +9,11 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
errors: [], errors: [],
customerBalance: config.customerBalance, customerBalance: config.customerBalance,
codeField: undefined, codeField: undefined,
alertMessage: {
content: "",
show: false,
timeout: null,
},
init() { init() {
// Fill the basket with the initial data // Fill the basket with the initial data
@ -33,7 +38,7 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
delete this.basket[id]; delete this.basket[id];
}, },
addToBasket(id: string, quantity: number): [boolean, string] { addToBasket(id: string, quantity: number): string {
const item: BasketItem = const item: BasketItem =
this.basket[id] || new BasketItem(config.products[id], 0); this.basket[id] || new BasketItem(config.products[id], 0);
@ -42,16 +47,20 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
if (item.quantity <= 0) { if (item.quantity <= 0) {
delete this.basket[id]; delete this.basket[id];
return [true, ""]; return "";
}
if (item.sum() > this.customerBalance) {
item.quantity = oldQty;
return [false, gettext("Not enough money")];
} }
this.basket[id] = item; this.basket[id] = item;
return [true, ""];
if (this.sumBasket() > this.customerBalance) {
item.quantity = oldQty;
if (item.quantity === 0) {
delete this.basket[id];
}
return gettext("Not enough money");
}
return "";
}, },
getBasketSize() { getBasketSize() {
@ -69,6 +78,25 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
return total; return total;
}, },
showAlertMessage(message: string) {
if (this.alertMessage.timeout !== null) {
clearTimeout(this.alertMessage.timeout);
}
this.alertMessage.content = message;
this.alertMessage.show = true;
this.alertMessage.timeout = setTimeout(() => {
this.alertMessage.show = false;
this.alertMessage.timeout = null;
}, 2000);
},
addToBasketWithMessage(id: string, quantity: number) {
const message = this.addToBasket(id, quantity);
if (message.length > 0) {
this.showAlertMessage(message);
}
},
onRefillingSuccess(event: CustomEvent) { onRefillingSuccess(event: CustomEvent) {
if (event.type !== "htmx:after-request" || event.detail.failed) { if (event.type !== "htmx:after-request" || event.detail.failed) {
return; return;
@ -81,9 +109,11 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
}, },
finish() { finish() {
if (this.getBasketSize() > 0) { if (this.getBasketSize() === 0) {
this.$refs.basketForm.submit(); this.showAlertMessage(gettext("You can't send an empty basket."));
return;
} }
this.$refs.basketForm.submit();
}, },
cancel() { cancel() {
@ -104,7 +134,7 @@ exportToHtml("loadCounter", (config: CounterConfig) => {
this.finish(); this.finish();
} }
} else { } else {
this.addToBasket(code, quantity); this.addToBasketWithMessage(code, quantity);
} }
this.codeField.widget.clear(); this.codeField.widget.clear();
this.codeField.widget.focus(); this.codeField.widget.focus();

View File

@ -31,6 +31,14 @@
<p class="important">Javascript is required for the counter UI.</p> <p class="important">Javascript is required for the counter UI.</p>
</noscript> </noscript>
<p
x-cloak
class="alert alert-red snackbar"
x-show="alertMessage.show"
x-transition.duration.500ms
x-text="alertMessage.content"
></p>
<div id="user_info"> <div id="user_info">
<h5>{% trans %}Customer{% endtrans %}</h5> <h5>{% trans %}Customer{% endtrans %}</h5>
{{ user_mini_profile(customer.user) }} {{ user_mini_profile(customer.user) }}
@ -92,9 +100,9 @@
</div> </div>
</template> </template>
<button @click.prevent="addToBasket(item.product.id, -1)">-</button> <button @click.prevent="addToBasketWithMessage(item.product.id, -1)">-</button>
<span x-text="item.quantity"></span> <span x-text="item.quantity"></span>
<button @click.prevent="addToBasket(item.product.id, 1)">+</button> <button @click.prevent="addToBasketWithMessage(item.product.id, 1)">+</button>
<span x-text="item.product.name"></span> : <span x-text="item.product.name"></span> :
<span x-text="item.sum().toLocaleString(undefined, { minimumFractionDigits: 2 })">€</span> <span x-text="item.sum().toLocaleString(undefined, { minimumFractionDigits: 2 })">€</span>
@ -163,7 +171,7 @@
<h5 class="margin-bottom">{{ category }}</h5> <h5 class="margin-bottom">{{ category }}</h5>
<div class="row gap-2x"> <div class="row gap-2x">
{% for product in categories[category] -%} {% for product in categories[category] -%}
<button class="card shadow" @click="addToBasket('{{ product.id }}', 1)"> <button class="card shadow" @click="addToBasketWithMessage('{{ product.id }}', 1)">
<strong class="card-title">{{ product.name }}</strong> <strong class="card-title">{{ product.name }}</strong>
<img <img
class="card-image" class="card-image"