parent
7f31708d86
commit
ca9c37f2c8
|
After Width: | Height: | Size: 162 KiB |
@ -0,0 +1,24 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 08:00 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0003_rename_productcolor_color_rename_productsize_size_and_more'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='cartitem', |
||||||
|
name='color', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.color'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='cartitem', |
||||||
|
name='size', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.size'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 08:59 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0004_cartitem_color_cartitem_size'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='color', |
||||||
|
name='name', |
||||||
|
field=models.CharField(choices=[('Red', 'Red'), ('Blue', 'Blue'), ('Green', 'Green'), ('Black', 'Black'), ('White', 'White')], max_length=20, unique=True), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='size', |
||||||
|
name='name', |
||||||
|
field=models.CharField(choices=[('S', 'Small'), ('M', 'Medium'), ('L', 'Large'), ('XL', 'X-Large'), ('SINGLE', 'Unique')], max_length=20, unique=True), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 13:46 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0005_alter_color_name_alter_size_name'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterModelOptions( |
||||||
|
name='product', |
||||||
|
options={'ordering': ['order']}, |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='product', |
||||||
|
name='order', |
||||||
|
field=models.IntegerField(default=0), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 13:49 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0006_alter_product_options_product_order'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='product', |
||||||
|
name='cut', |
||||||
|
field=models.IntegerField(choices=[(1, 'Women'), (2, 'Men'), (3, 'Kids')], default=2), |
||||||
|
), |
||||||
|
] |
||||||
@ -1,37 +1,124 @@ |
|||||||
|
.options-container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 1fr 1fr 1fr; |
||||||
|
column-gap: 8px; |
||||||
|
align-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.no-image, |
||||||
.product-image { |
.product-image { |
||||||
|
height: 240px; |
||||||
width: 100%; |
width: 100%; |
||||||
height: 180px; |
object-fit: contain; /* This will maintain the aspect ratio of the image */ |
||||||
object-fit: contain; |
background-color: black; |
||||||
display: block; |
|
||||||
margin: 0 auto; |
|
||||||
} |
} |
||||||
|
|
||||||
.bubble { |
.no-image { |
||||||
width: 100%; |
background-color: white; |
||||||
height: 365px; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
} |
} |
||||||
|
|
||||||
.bubble h3 { |
.product-title { |
||||||
margin-top: 10px; |
font-size: 16px; /* Increase the font size for a bigger title */ |
||||||
font-size: 1.2em; |
font-weight: bold; /* Make the title bold */ |
||||||
flex-grow: 1; |
|
||||||
} |
} |
||||||
|
|
||||||
.product-price { |
.product-price { |
||||||
font-weight: bold; |
font-size: 16px; /* Increase the font size for a bigger title */ |
||||||
color: #f39200; |
font-weight: bold; /* Make the title bold */ |
||||||
margin: 10px 0; |
} |
||||||
|
|
||||||
|
.option-element { |
||||||
|
align-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.option-element:nth-child(1) { |
||||||
|
grid-column: 1 / span 2; |
||||||
|
grid-row: 1; |
||||||
|
height: 64px; |
||||||
|
} |
||||||
|
|
||||||
|
.option-element:nth-child(2) { |
||||||
|
grid-column: 3; |
||||||
|
grid-row: 1; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.option-element:nth-child(3) { |
||||||
|
grid-column: 1; |
||||||
|
grid-row: 2; |
||||||
|
} |
||||||
|
.option-element:nth-child(4) { |
||||||
|
grid-column: 2; |
||||||
|
grid-row: 2; |
||||||
|
} |
||||||
|
.option-element:nth-child(5) { |
||||||
|
grid-column: 3; |
||||||
|
grid-row: 2; |
||||||
|
} |
||||||
|
|
||||||
|
.option-element:nth-child(6) { |
||||||
|
grid-column: 1 / span 2; |
||||||
|
grid-row: 3; |
||||||
|
} |
||||||
|
.option-element:nth-child(7) { |
||||||
|
grid-column: 3; |
||||||
|
grid-row: 3; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.add-to-cart-button { |
||||||
|
margin-top: 10px; |
||||||
|
width: 100%; |
||||||
|
background-color: #90ee90; /* Green background */ |
||||||
|
text-align: center; |
||||||
|
display: inline-block; |
||||||
|
height: 40px; /* Set the height to 40 pixels */ |
||||||
|
transition: background-color 0.3s ease; /* Smooth transition on hover */ |
||||||
|
color: #707070; |
||||||
|
border-radius: 12px; |
||||||
|
text-decoration: none; |
||||||
|
font-size: 12px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
|
||||||
|
.add-to-cart-button:hover { |
||||||
|
background-color: #f39200; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.confirm-nav-button { |
||||||
|
background-color: #90ee90; |
||||||
|
} |
||||||
|
|
||||||
|
.cancel-nav-button { |
||||||
|
background-color: #e84039; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.confirm-nav-button:hover, |
||||||
|
.cancel-nav-button:hover { |
||||||
|
background-color: orange; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.cart-table tbody tr.odd { |
||||||
|
background-color: #f0f0f0; |
||||||
|
} |
||||||
|
|
||||||
|
.cart-table tbody tr.even { |
||||||
|
background-color: #e8e8e8; |
||||||
} |
} |
||||||
|
|
||||||
.add-to-cart-form { |
.cart-table th.price-column, |
||||||
display: flex; |
.cart-table td.price-column { |
||||||
gap: 10px; |
text-align: right; |
||||||
margin-top: auto; |
|
||||||
} |
} |
||||||
|
|
||||||
.quantity-input { |
.cart-table tfoot .total-label { |
||||||
width: 50px; |
font-weight: bold; |
||||||
padding: 5px; |
} |
||||||
|
|
||||||
|
.cart-table tfoot .total-price { |
||||||
|
font-weight: bold; |
||||||
|
font-size: 1.2em; |
||||||
} |
} |
||||||
|
|||||||
@ -1,17 +1,56 @@ |
|||||||
<div class="cell small-12 medium-4 large-3 my-block"> |
<div class="small-12 medium-4 large-3 my-block"> |
||||||
<div class="bubble"> |
<div class="bubble"> |
||||||
{% if product.image %} |
{% if product.image %} |
||||||
<img src="{{ product.image.url }}" alt="{{ product.title }}" class="product-image"> |
<img src="{{ product.image.url }}" alt="{{ product.title }}" class="product-image"> |
||||||
{% else %} |
{% else %} |
||||||
<div class="no-image">No Image Available</div> |
<div class="no-image">No Image Available</div> |
||||||
{% endif %} |
{% endif %} |
||||||
<h3>{{ product.title }}</h3> |
|
||||||
<div class="product-price">{{ product.price }} €</div> |
|
||||||
|
|
||||||
<form method="post" action="{% url 'shop:add_to_cart' product.id %}" class="add-to-cart-form"> |
<form method="post" action="{% url 'shop:add_to_cart' product.id %}" class="add-to-cart-form"> |
||||||
{% csrf_token %} |
{% csrf_token %} |
||||||
<input type="number" name="quantity" value="1" min="1" max="10" class="quantity-input"> |
<div class="options-container"> |
||||||
<button type="submit" class="btn styled-link">Ajouter au panier</button> |
<div class="option-element product-title">{{ product.title }}</div> |
||||||
|
<div class="option-element product-price">{{ product.price }} €</div> |
||||||
|
<div class="option-element form-group"> |
||||||
|
{% if product.colors.exists %} |
||||||
|
<select name="color" id="color-{{ product.id }}" class="form-control" required> |
||||||
|
<option value="" disabled selected>Couleur</option> |
||||||
|
{% for color in product.colors.all %} |
||||||
|
<option value="{{ color.id }}" {% if forloop.first %}selected{% endif %}>{{ color.name }}</option> |
||||||
|
{% endfor %} |
||||||
|
</select> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="option-element form-group"> |
||||||
|
{% if product.sizes.exists %} |
||||||
|
<select name="size" id="size-{{ product.id }}" class="form-control" required> |
||||||
|
<option value="" disabled selected>Taille</option> |
||||||
|
{% for size in product.sizes.all %} |
||||||
|
<option value="{{ size.id }}" {% if forloop.first %}selected{% endif %}>{{ size.name }}</option> |
||||||
|
{% endfor %} |
||||||
|
</select> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
<div class="option-element form-group quantity-group"> |
||||||
|
<input type="number" id="quantity-{{ product.id }}" name="quantity" value="1" min="1" max="10" class="quantity-input" oninput="updateTotal({{ product.id }}, {{ product.price }})"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="option-element form-group">Total</div> |
||||||
|
<div class="option-element form-group"><span id="total-price-{{ product.id }}">{{ product.price }}</span> €</div> |
||||||
|
</div> |
||||||
|
<button type="submit" class="add-to-cart-button">Ajouter au panier</button> |
||||||
</form> |
</form> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
function updateTotal(productId, price) { |
||||||
|
let quantityInput = document.getElementById(`quantity-${productId}`); |
||||||
|
let totalPriceElement = document.getElementById(`total-price-${productId}`); |
||||||
|
|
||||||
|
let quantity = parseInt(quantityInput.value) || 1; // Default to 1 if invalid |
||||||
|
let totalPrice = (quantity * price).toFixed(2); // Ensure two decimal places |
||||||
|
|
||||||
|
totalPriceElement.textContent = totalPrice; |
||||||
|
} |
||||||
|
</script> |
||||||
|
|||||||
Loading…
Reference in new issue