You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
padelclub_backend/shop/templates/shop/cart.html

292 lines
12 KiB

{% extends 'tournaments/base.html' %}
{% block head_title %}La Boutique{% endblock %}
{% block first_title %}Padel Club{% endblock %}
{% block second_title %}La Boutique{% endblock %}
{% block content %}
<nav class="margin10">
<a href="{% url 'shop:product_list' %}">La Boutique</a>
<a href="{% url 'index' %}" class="orange">Accueil</a>
<a href="{% url 'clubs' %}" class="orange">Clubs</a>
{% if user.is_authenticated %}
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a>
<a href="{% url 'profile' %}">Mon compte</a>
{% else %}
<a href="{% url 'login' %}">Se connecter</a>
{% endif %}
</nav>
{% if STRIPE_IS_TEST_MODE %}
<div class="alert alert-warning" style="background-color: #fff3cd; color: #856404; padding: 10px; margin: 10px 0; border-radius: 5px; border: 1px solid #ffeeba;">
<strong> Test Mode:</strong> Stripe is currently in test mode. No real payments will be processed.
<br>
<small>Use test card: 4242 4242 4242 4242 with any future date and any CVC.</small>
</div>
{% endif %}
<div class="grid-x">
<div class="small-12 medium-9 large-6 padding10">
<h1 class="club padding10 topmargin20">Votre panier</h1>
<div class="bubble">
{% if display_data.items %}
<div class="info-box" style="background-color: #f8f9fa; border-left: 4px solid #4e73df; padding: 15px; margin: 15px 0; border-radius: 5px;">
<h4 style="color: #4e73df; margin-top: 0;">Comment fonctionne la livraison ?</h4>
<p>Cette boutique fonctionne entre amis 'Padel Club'. Les commandes sont :</p>
<ol style="padding-left: 20px; margin-bottom: 0;">
<li>Passées en ligne via notre système</li>
<li>Préparées par notre équipe</li>
<li>Remises en main propre lors d'une prochaine session de padel</li>
</ol>
<p style="margin-top: 10px; margin-bottom: 0;">Pas d'expédition : nous vous remettrons votre commande personnellement au club !</p>
</div>
{% include 'shop/partials/order_items_display.html' with items=display_data.items total_quantity=display_data.total_quantity total_price=display_data.total_price edit_mode=True %}
<div class="coupon-section">
<div>Avez-vous un code de réduction?</div>
<div class="coupon-form" style="display: flex;">
<input type="text" id="coupon-code" style="flex-grow: 1; margin-right: 10px; border-radius: 12px" placeholder="Entrez votre code">
<button id="apply-coupon" class="confirm-nav-button" style="min-width: 100px; border-radius: 12px; height: 40px;">Appliquer</button>
<button id="remove-coupon" class="cancel-nav-button" style="min-width: 100px; border-radius: 12px; height: 40px; display: none;">Supprimer</button>
</div>
<div id="coupon-message"></div>
<!-- Discount display -->
<div id="discount-info" style="margin-top: 10px; display: none;">
<div class="discount-row" style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<span>Sous-total:</span>
<span id="subtotal-amount">€{{ display_data.total_price }}</span>
</div>
<div class="discount-row" style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<span>Réduction:</span>
<span id="discount-amount" style="color: #e67e22;">-€0.00</span>
</div>
<div class="discount-row" style="display: flex; justify-content: space-between; font-weight: bold;">
<span>Total:</span>
<span id="final-total">€{{ display_data.total_price }}</span>
</div>
</div>
</div>
<div class="cart-summary">
{% if user.is_authenticated %}
<!-- For authenticated users: Direct Stripe payment button -->
<button id="checkout-button" class="confirm-nav-button checkout-button">Procéder au paiement</button>
{% else %}
<!-- For guest users: Regular checkout path -->
<a class="confirm-nav-button checkout-button" href="{% url 'shop:checkout' %}">Passer la commande</a>
<div class="guest-checkout-notice">
<p>Connectez-vous pour un paiement plus rapide.</p>
<a class="styled-link" href="{% url 'login' %}?next={% url 'shop:view_cart' %}">Se connecter</a>
</div>
{% endif %}
<hr>
{% if display_data.items %}
<a class="cancel-nav-button checkout-button" href="{% url 'shop:clear_cart' %}" onclick="return confirm('Êtes-vous sûr de vouloir supprimer votre panier ?');">Vider le panier</a>
{% endif %}
<!-- Debug buttons -->
{% if settings.DEBUG %}
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px dashed #ccc;">
<h3>Debug Payment Simulation</h3>
<div style="display: flex; gap: 10px;">
<a class="confirm-nav-button checkout-button" href="{% url 'shop:simulate_payment_success' %}" style="background-color: #28a745;">
Simuler Paiement Réussi
</a>
<a class="cancel-nav-button checkout-button" href="{% url 'shop:simulate_payment_failure' %}" style="background-color: #dc3545;">
Simuler Paiement Échoué
</a>
</div>
</div>
{% endif %}
</div>
{% else %}
<p>Votre panier est vide.</p>
<a class="confirm-nav-button checkout-button" href="{% url 'shop:product_list' %}">Retourner à la boutique</a>
{% endif %}
</div>
</div>
</div>
{% if user.is_authenticated and display_data.items %}
<!-- Stripe JavaScript for authenticated users -->
<script src="https://js.stripe.com/v3/"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const checkoutButton = document.getElementById('checkout-button');
const applyButton = document.getElementById('apply-coupon');
const removeButton = document.getElementById('remove-coupon');
const codeInput = document.getElementById('coupon-code');
const messageElement = document.getElementById('coupon-message');
const discountInfo = document.getElementById('discount-info');
const subtotalAmount = document.getElementById('subtotal-amount');
const discountAmount = document.getElementById('discount-amount');
const finalTotal = document.getElementById('final-total');
// Initial values
const originalTotal = parseFloat('{{ display_data.total_price }}');
// Function to get CSRF token
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue; // FIX: Proper closing of the function here
}
// Apply coupon
applyButton.addEventListener('click', function() {
const code = codeInput.value.trim();
if (!code) {
messageElement.textContent = 'Veuillez entrer un code';
messageElement.style.color = '#e74c3c';
return;
}
// Show loading state
applyButton.textContent = 'Chargement...';
applyButton.disabled = true;
// Send request to server
fetch('{% url "shop:apply_coupon" %}', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': getCookie('csrftoken')
},
body: `code=${encodeURIComponent(code)}`
})
.then(response => response.json())
.then(data => {
// Reset button state
applyButton.textContent = 'Appliquer';
applyButton.disabled = false;
// Show message
messageElement.textContent = data.message;
if (data.status === 'success') {
// Update UI for success
messageElement.style.color = '#27ae60';
applyButton.style.display = 'none';
removeButton.style.display = 'block';
codeInput.disabled = true;
// Update price display
discountInfo.style.display = 'block';
discountAmount.textContent = `-€${data.discount.toFixed(2)}`;
finalTotal.textContent = `${data.new_total.toFixed(2)}`;
} else {
// Update UI for error
messageElement.style.color = '#e74c3c';
}
})
.catch(error => {
console.error('Error:', error);
applyButton.textContent = 'Appliquer';
applyButton.disabled = false;
messageElement.textContent = 'Une erreur est survenue. Veuillez réessayer.';
messageElement.style.color = '#e74c3c';
});
});
// Remove coupon
removeButton.addEventListener('click', function() {
// Show loading state
removeButton.textContent = 'Chargement...';
removeButton.disabled = true;
// Send request to server
fetch('{% url "shop:remove_coupon" %}', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': getCookie('csrftoken')
}
})
.then(response => response.json())
.then(data => {
// Reset button state
removeButton.textContent = 'Supprimer';
removeButton.disabled = false;
if (data.status === 'success') {
// Reset UI
messageElement.textContent = '';
codeInput.value = '';
codeInput.disabled = false;
applyButton.style.display = 'block';
removeButton.style.display = 'none';
discountInfo.style.display = 'none';
finalTotal.textContent = `${originalTotal.toFixed(2)}`;
}
})
.catch(error => {
console.error('Error:', error);
removeButton.textContent = 'Supprimer';
removeButton.disabled = false;
messageElement.textContent = 'Une erreur est survenue. Veuillez réessayer.';
messageElement.style.color = '#e74c3c';
});
});
checkoutButton.addEventListener('click', function() {
// Show a loading indicator
checkoutButton.textContent = 'Chargement...';
checkoutButton.disabled = true;
// Create order and get checkout session
fetch('{% url "shop:create_checkout_session" %}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
credentials: 'same-origin',
})
.then(function(response) {
return response.json();
})
.then(function(session) {
if (session.error) {
// Handle error
alert(session.error);
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
return;
}
// Initialize Stripe
const stripe = Stripe('{{ stripe_publishable_key }}');
// Redirect to Stripe Checkout
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function(result) {
// If redirectToCheckout fails
if (result && result.error) {
alert(result.error.message);
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
}
})
.catch(function(error) {
console.error('Error:', error);
alert('Une erreur est survenue. Veuillez réessayer.');
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
});
});
});
</script>
{% endif %}
{% endblock %}