feat(ui): replace alert notifications with toast messages

Add toast notification functionality using Bootstrap Toasts and update
checkout success/error handling to use toast messages instead of alert boxes.

**Changes:**
- Add `showToast` function to `terminal.js`
- Add toast container and templates to `terminal.html`
- Replace alert() calls in handleCheckoutSubmit with showToast()
This commit is contained in:
2026-01-26 17:44:03 +03:00
parent b24a0d9f21
commit 5700314b10
2 changed files with 58 additions and 4 deletions

View File

@@ -12,6 +12,38 @@ function roundQuantity(value, decimals = 3) {
return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals); return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
} }
/**
* Показывает toast уведомление в правом верхнем углу
* @param {string} type - 'success' или 'error'
* @param {string} message - Текст сообщения
*/
function showToast(type, message) {
const toastId = type === 'success' ? 'orderSuccessToast' : 'orderErrorToast';
const messageId = type === 'success' ? 'toastMessage' : 'errorMessage';
const bgClass = type === 'success' ? 'bg-success' : 'bg-danger';
const toastElement = document.getElementById(toastId);
const messageElement = document.getElementById(messageId);
// Устанавливаем сообщение
messageElement.textContent = message;
// Добавляем цвет фона
toastElement.classList.add(bgClass, 'text-white');
// Создаём и показываем toast (автоматически скроется через 3 секунды)
const toast = new bootstrap.Toast(toastElement, {
delay: 3000,
autohide: true
});
toast.show();
// Убираем класс цвета после скрытия
toastElement.addEventListener('hidden.bs.toast', () => {
toastElement.classList.remove(bgClass, 'text-white');
}, { once: true });
}
const CATEGORIES = JSON.parse(document.getElementById('categoriesData').textContent); const CATEGORIES = JSON.parse(document.getElementById('categoriesData').textContent);
let ITEMS = []; // Будем загружать через API let ITEMS = []; // Будем загружать через API
let showcaseKits = JSON.parse(document.getElementById('showcaseKitsData').textContent); let showcaseKits = JSON.parse(document.getElementById('showcaseKitsData').textContent);
@@ -3415,8 +3447,8 @@ async function handleCheckoutSubmit(paymentsData) {
if (result.success) { if (result.success) {
console.log('✅ Заказ успешно создан:', result); console.log('✅ Заказ успешно создан:', result);
// Успех // Показываем toast уведомление
alert(`Заказ #${result.order_number} успешно создан!\nСумма: ${result.total_amount.toFixed(2)} руб.`); showToast('success', `Заказ #${result.order_number} успешно создан! Сумма: ${result.total_amount.toFixed(2)} руб.`);
// Очищаем корзину // Очищаем корзину
cart.clear(); cart.clear();
@@ -3437,12 +3469,12 @@ async function handleCheckoutSubmit(paymentsData) {
}, 500); }, 500);
} else { } else {
alert('Ошибка: ' + result.error); showToast('error', 'Ошибка: ' + result.error);
} }
} catch (error) { } catch (error) {
console.error('Ошибка checkout:', error); console.error('Ошибка checkout:', error);
alert('Ошибка при проведении продажи: ' + error.message); showToast('error', 'Ошибка при проведении продажи: ' + error.message);
} finally { } finally {
// Разблокируем кнопку // Разблокируем кнопку
const btn = document.getElementById('confirmCheckoutBtn'); const btn = document.getElementById('confirmCheckoutBtn');

View File

@@ -729,6 +729,28 @@
<!-- Модалка редактирования товара в корзине --> <!-- Модалка редактирования товара в корзине -->
{% include 'pos/components/edit_cart_item_modal.html' %} {% include 'pos/components/edit_cart_item_modal.html' %}
<!-- Toast Container для уведомлений -->
<div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 1060;">
<div id="orderSuccessToast" class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
<i class="bi bi-check-circle-fill text-success me-2 fs-5"></i>
<span id="toastMessage"></span>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close" style="display: none;"></button>
</div>
</div>
<div id="orderErrorToast" class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
<i class="bi bi-exclamation-circle-fill text-danger me-2 fs-5"></i>
<span id="errorMessage"></span>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}