feat: implement order management and checkout functionality
All checks were successful
Build and Push Docker Image / build (push) Successful in 50s

- Added `Order` and `OrderItem` models with migrations for managing orders and their details
- Created `CheckoutForm` for validating order data and customer information
- Built templates for order confirmation, checkout success, and emails (HTML and plain text)
- Added logic for email notifications upon successful order placement
- Enhanced shopping cart template with checkout panel integration
- Updated styles and JavaScript for streamlined checkout UX
- Refactored cart view to support item summaries and final totals during checkout
This commit is contained in:
2026-05-25 16:45:42 +02:00
parent 438d547fb4
commit 81e30f853d
16 changed files with 1271 additions and 262 deletions

View File

@@ -17,4 +17,46 @@ document.addEventListener('DOMContentLoaded', function () {
}
});
});
const checkoutForm = document.querySelector('[data-checkout-form]');
if (!checkoutForm) {
return;
}
const productsTotal = Number(checkoutForm.dataset.productsTotal || '0');
const deliveryPrice = 500;
const floorLiftPrice = 45;
const totalNodes = document.querySelectorAll('[data-checkout-total-text]');
const deliveryNode = document.querySelector('[data-delivery-total-text]');
const floorLiftNode = document.querySelector('[data-floor-lift-total-text]');
const formatCurrency = function (value) {
return new Intl.NumberFormat('ru-RU', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(value) + ' руб.';
};
const updateCheckoutTotals = function () {
const selectedDelivery = checkoutForm.querySelector('input[name="delivery_method"]:checked');
const hasDelivery = selectedDelivery && selectedDelivery.value === 'courier';
const deliveryTotal = hasDelivery ? deliveryPrice : 0;
const floorLiftTotal = hasDelivery ? floorLiftPrice : 0;
const total = productsTotal + deliveryTotal + floorLiftTotal;
totalNodes.forEach(function (node) {
node.textContent = formatCurrency(total);
});
if (deliveryNode) {
deliveryNode.textContent = formatCurrency(deliveryTotal);
}
if (floorLiftNode) {
floorLiftNode.textContent = formatCurrency(floorLiftTotal);
}
};
checkoutForm.querySelectorAll('input[name="delivery_method"]').forEach(function (input) {
input.addEventListener('change', updateCheckoutTotals);
});
updateCheckoutTotals();
});