UI cleanup and fixes

This commit is contained in:
Nathan Chapman 2022-04-05 10:04:24 -06:00
parent 5400002772
commit f55a87dca4
12 changed files with 150 additions and 89 deletions

View File

@ -2,9 +2,11 @@
{% block content %} {% block content %}
<article class="product"> <article class="product">
<h1>Create product</h1> <header class="object__header">
<section> <h1>Create product</h1>
<form method="POST" action="{% url 'dashboard:product-create' %}"> </header>
<section class="object__panel">
<form class="panel__item" method="POST" action="{% url 'dashboard:product-create' %}">
{% csrf_token %} {% csrf_token %}
{{form.as_p}} {{form.as_p}}
<p class="form__submit"> <p class="form__submit">

View File

@ -116,9 +116,10 @@ class OrderListView(LoginRequiredMixin, ListView):
def get_queryset(self): def get_queryset(self):
query = self.request.GET.get('status') query = self.request.GET.get('status')
if query: if query == 'unfulfilled':
object_list = Order.objects.filter( object_list = Order.objects.filter(
status=query Q(status=OrderStatus.UNFULFILLED) |
Q(status=OrderStatus.PARTIALLY_FULFILLED)
).order_by( ).order_by(
'-created_at' '-created_at'
).select_related( ).select_related(

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -202,12 +202,23 @@ img {
max-width: 100%; max-width: 100%;
} }
.fair_trade--small {
max-width: 4rem;
vertical-align: middle;
}
.product__item { .product__item {
display: grid; display: grid;
grid-template-columns: 2fr 1fr; grid-template-columns: 2fr 1fr;
gap: 0 2rem; gap: 0 2rem;
} }
@media (max-width: 876px) {
.product__item {
grid-template-columns: 1fr;
}
}
.product__list-item button { .product__list-item button {
grid-column: 1/3; grid-column: 1/3;
align-self: end; align-self: end;
@ -222,17 +233,17 @@ img {
.product__form { .product__form {
display: grid; display: grid;
grid-template-columns: 1fr 3fr; grid-template-columns: 1fr 1fr 1fr;
gap: 1rem; gap: 1rem;
} }
.product__form input[type=submit] { .product__form input[type=submit] {
grid-column: 2; /*grid-column: 2;*/
justify-self: end; justify-self: end;
} }
.site__logo { .site-logo {
height: 3rem; height: 4rem;
vertical-align: middle; vertical-align: middle;
} }
@ -257,10 +268,55 @@ nav a {
text-decoration: none; text-decoration: none;
} }
nav a:not(:last-child) {
margin-right: 2rem;
}
nav { nav {
margin-bottom: 4rem; margin-bottom: 4rem;
} }
.has-menu {
position: relative;
}
.has-menu a {
text-transform: lowercase;
font-variant: small-caps;
font-weight: bold;
text-decoration: none;
}
.has-menu:hover .dropdown-menu {
display: unset;
}
[role="menu"] {
list-style: none;
margin: 0;
padding: 0;
}
[role="menuitem"] {
cursor: pointer;
position: relative;
}
[role="menuitem"]:not(:last-child) {
margin-bottom: 0.5rem;
}
.dropdown-menu {
background-color: var(--bg-color);
border: var(--default-border);
padding: 0.5rem;
position: absolute;
top: 100%;
right: 0;
z-index: 1000;
display: none;
}
.site__copyright { .site__copyright {
text-align: center; text-align: center;
} }
@ -270,20 +326,31 @@ nav {
grid-template-columns: 1fr 2fr; grid-template-columns: 1fr 2fr;
gap: 2rem; gap: 2rem;
} }
.keep_calm__img { .keep_calm__img {
max-width: 250px; max-width: 250px;
} }
@media (max-width: 564px) {
.keep_calm {
grid-template-columns: 1fr;
}
.keep_calm figure {
text-align: center;
}
}
.site__cart { .site__cart {
display: flex; display: flex;
align-items: center; align-items: center;
background-color: var(--yellow-color); background-color: var(--yellow-color);
padding: 0.25rem 1rem; padding: 0 1rem;
text-decoration: none; text-decoration: none;
border-radius: 0.2rem; border-radius: 0.2rem;
color: var(--fg-color); color: var(--fg-color);
cursor: pointer; cursor: pointer;
margin-left: 2rem;
} }
@ -337,6 +404,13 @@ nav {
gap: 8rem; gap: 8rem;
} }
@media (max-width: 911px) {
.product__list {
grid-template-columns: 1fr;
gap: 4rem;
}
}
.product__list-item { .product__list-item {
text-decoration: none; text-decoration: none;
display: grid; display: grid;
@ -384,6 +458,7 @@ footer {
.object__header { .object__header {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
@ -437,6 +512,10 @@ footer {
gap: 2rem; gap: 2rem;
} }
.fair-trade-stamp {
text-align: center;
}
.user__emails { .user__emails {
margin-bottom: 4rem; margin-bottom: 4rem;

View File

@ -23,12 +23,12 @@ class Cart:
cart = self.session[settings.CART_SESSION_ID] = {} cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart self.cart = cart
def add(self, product, quantity=1, roast='', update_quantity=False): def add(self, product, quantity=1, grind='', update_quantity=False):
product_id = str(product.id) product_id = str(product.id)
if product_id not in self.cart: if product_id not in self.cart:
self.cart[product_id] = { self.cart[product_id] = {
'quantity': 0, 'quantity': 0,
'roast': roast, 'grind': grind,
'price': str(product.price) 'price': str(product.price)
} }
@ -68,7 +68,7 @@ class Cart:
def clear(self): def clear(self):
del self.session[settings.CART_SESSION_ID] del self.session[settings.CART_SESSION_ID]
del self.session[self.coupon_code] del self.session['coupon_code']
self.session.modified = True self.session.modified = True
def build_order_params(self): def build_order_params(self):
@ -94,7 +94,7 @@ class Cart:
bulk_list = [OrderLine( bulk_list = [OrderLine(
order=order, order=order,
product=item['product'], product=item['product'],
customer_note=item['roast'], customer_note=item['grind'],
unit_price=item['price'], unit_price=item['price'],
quantity=item['quantity'], quantity=item['quantity'],
tax_rate=2, tax_rate=2,

View File

@ -19,7 +19,7 @@ class AddToCartForm(forms.Form):
AEROPRESS = 'AeroPress' AEROPRESS = 'AeroPress'
PERCOLATOR = 'Percolator' PERCOLATOR = 'Percolator'
OTHER = 'Other' OTHER = 'Other'
ROAST_CHOICES = [ GRIND_CHOICES = [
(WHOLE, 'Whole Beans'), (WHOLE, 'Whole Beans'),
(ESPRESSO, 'Espresso'), (ESPRESSO, 'Espresso'),
(CONE_DRIP, 'Cone Drip'), (CONE_DRIP, 'Cone Drip'),
@ -31,11 +31,11 @@ class AddToCartForm(forms.Form):
(OTHER, 'Other (enter below)') (OTHER, 'Other (enter below)')
] ]
quantity = forms.IntegerField(min_value=1, initial=1) quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)
roast = forms.ChoiceField(choices=ROAST_CHOICES) grind = forms.ChoiceField(choices=GRIND_CHOICES)
class UpdateCartItemForm(forms.Form): class UpdateCartItemForm(forms.Form):
quantity = forms.IntegerField(min_value=1, initial=1) quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)
update = forms.BooleanField(required=False, initial=True, widget=forms.HiddenInput) update = forms.BooleanField(required=False, initial=True, widget=forms.HiddenInput)
@ -49,7 +49,7 @@ class AddToSubscriptionForm(forms.Form):
AEROPRESS = 'AeroPress' AEROPRESS = 'AeroPress'
PERCOLATOR = 'Percolator' PERCOLATOR = 'Percolator'
OTHER = 'Other' OTHER = 'Other'
ROAST_CHOICES = [ GRIND_CHOICES = [
(WHOLE, 'Whole Beans'), (WHOLE, 'Whole Beans'),
(ESPRESSO, 'Espresso'), (ESPRESSO, 'Espresso'),
(CONE_DRIP, 'Cone Drip'), (CONE_DRIP, 'Cone Drip'),
@ -71,7 +71,7 @@ class AddToSubscriptionForm(forms.Form):
] ]
quantity = forms.IntegerField(min_value=1, initial=1) quantity = forms.IntegerField(min_value=1, initial=1)
roast = forms.ChoiceField(choices=ROAST_CHOICES) grind = forms.ChoiceField(choices=GRIND_CHOICES)
schedule = forms.ChoiceField(choices=SCHEDULE_CHOICES) schedule = forms.ChoiceField(choices=SCHEDULE_CHOICES)

View File

@ -13,21 +13,24 @@
<img class="product__image product__image--small" src="{{product.productphoto_set.first.image.url}}" alt="{{product.productphoto_set.first.image}}"> <img class="product__image product__image--small" src="{{product.productphoto_set.first.image.url}}" alt="{{product.productphoto_set.first.image}}">
</figure> </figure>
<div class="item__details"> <div class="item__details">
<p>{{product.name}}<br> ${{item.price}}</p> <p><strong>{{product.name}}</strong></p>
<p>{{item.roast}}</p> <p><strong>${{item.price}}</strong></p>
<p> <p><strong>Grind</strong>: {{item.grind}}</p>
<a href="{% url 'storefront:cart-remove' product.pk %}">Remove from cart</a>
</p>
<form class="product__form" action="{% url 'storefront:cart-update' product.pk %}" method="POST"> <form class="product__form" action="{% url 'storefront:cart-update' product.pk %}" method="POST">
{% csrf_token %} {% csrf_token %}
{{ item.update_quantity_form }} {{ item.update_quantity_form }}
<input type="submit" value="Update"> <input type="submit" value="Update">
</form> </form>
<p>
<a href="{% url 'storefront:cart-remove' product.pk %}">Remove from cart</a>
</p>
</div> </div>
{% endwith %} {% endwith %}
</div> </div>
{% empty %} {% empty %}
<p>No items in cart yet.</p> <div class="panel__item">
<p>No items in cart yet.</p>
</div>
{% endfor %} {% endfor %}
</section> </section>
<section class="object__panel"> <section class="object__panel">
@ -52,7 +55,7 @@
<span><strong>Cart total: ${{cart.get_total_price_after_discount|floatformat:"2"}}</strong></span> <span><strong>Cart total: ${{cart.get_total_price_after_discount|floatformat:"2"}}</strong></span>
</p> </p>
<p class="cart__total"> <p class="cart__total">
<a href="{% url 'storefront:product-list' %}">Continue Shopping</a>&emsp;or&emsp;<a class="action-button action-button--large" href="{% url 'storefront:checkout-address' %}">Proceed to Checkout</a> <a href="{% url 'storefront:product-list' %}">Continue Shopping</a>{% if cart|length > 0 %}&emsp;or&emsp;<a class="action-button action-button--large" href="{% url 'storefront:checkout-address' %}">Proceed to Checkout</a>{% endif %}
</p> </p>
</div> </div>
</section> </section>

View File

@ -51,6 +51,9 @@
</div> </div>
</section> </section>
{% with order_list=customer.orders.all %} {% with order_list=customer.orders.all %}
<header class="object__header">
<h3>Your orders</h3>
</header>
<section class="object__list"> <section class="object__list">
<div class="object__item panel__header object__item--col3" href="order-detail"> <div class="object__item panel__header object__item--col3" href="order-detail">
<span>Order #</span> <span>Order #</span>

View File

@ -34,9 +34,10 @@
<img class="product__image product__image--small" src="{{product.productphoto_set.first.image.url}}" alt="{{product.productphoto_set.first.image}}"> <img class="product__image product__image--small" src="{{product.productphoto_set.first.image.url}}" alt="{{product.productphoto_set.first.image}}">
</figure> </figure>
<div class="item__details"> <div class="item__details">
<p>{{product.name}}<br> ${{item.price}}</p> <p><strong>{{product.name}}</strong></p>
<p><strong>${{item.price}}</strong></p>
<p><strong>Quantity</strong>: {{item.quantity}}</p> <p><strong>Quantity</strong>: {{item.quantity}}</p>
<p><strong>Grind options</strong>: {{item.roast}}</p> <p><strong>Grind options</strong>: {{item.grind}}</p>
</div> </div>
{% endwith %} {% endwith %}
</div> </div>

View File

@ -13,21 +13,16 @@
<section> <section>
<h1>{{product.name}}</h1> <h1>{{product.name}}</h1>
<p>{{product.description}}</p> <p>{{product.description}}</p>
<p class="fair-trade-stamp"><img class="fair_trade--small" src="{% static 'images/fair_trade_stamp.png' %}" alt=""></p>
<p>$<strong>{{product.price}}</strong></p> <p>$<strong>{{product.price}}</strong></p>
<p>{{product.weight.oz}} oz</p> <p>{{product.weight.oz}} oz</p>
<form method="post" action="{% url 'storefront:cart-add' product.pk %}"> <form method="post" action="{% url 'storefront:cart-add' product.pk %}">
{% csrf_token %} {% csrf_token %}
<h3>One-time purchase</h3>
{{ form.as_p }} {{ form.as_p }}
<p> <p>
<input type="submit" value="Add to cart" class="action-button"> <input type="submit" value="Add to cart" class="action-button">
</p> </p>
</form> </form>
<br><hr><br>
<form action="">
<h3>Subscribe and save 10%</h3>
</form>
Subscriptions
</section> </section>
</article> </article>
{% endblock %} {% endblock %}

View File

@ -62,7 +62,7 @@ class CartAddProductView(SingleObjectMixin, FormView):
if form.is_valid(): if form.is_valid():
cart.add( cart.add(
product=self.get_object(), product=self.get_object(),
roast=form.cleaned_data['roast'], grind=form.cleaned_data['grind'],
quantity=form.cleaned_data['quantity'] quantity=form.cleaned_data['quantity']
) )
return self.form_valid(form) return self.form_valid(form)

View File

@ -25,34 +25,37 @@
<body> <body>
<header class="site__header"> <header class="site__header">
<div> <div>
<a href="{% url 'storefront:product-list' %}"><img class="site__logo" src="{% static 'images/site_logo.svg' %}" alt=""></a> <a href="{% url 'storefront:product-list' %}"><img class="site-logo" src="{% static 'images/site_logo.svg' %}" alt=""></a>
{% if user.is_authenticated %} <nav>
<span> <a href="{% url 'storefront:product-list' %}">Shop</a>
Hi <a href="{% url 'storefront:customer-detail' user.pk %}">{{user.first_name}} {{user.last_name}}</a>! <a href="">Cafe</a>
</span> <a href="">Fair Trade</a>
{% if user.is_staff %} <a href="{% url 'storefront:about' %}">About</a>
<span><a href="{% url 'dashboard:home' %}">Dashboard</a></span> <a href="{% url 'storefront:contact' %}">Contact</a>
</nav>
<div>
{% if user.is_authenticated %}
<div class="has-menu">
<a href="{% url 'storefront:customer-detail' user.pk %}">Account ▼</a>
<ul role="menu" class="dropdown-menu">
{% if user.is_staff %}
<li role="menuitem"><a href="{% url 'dashboard:home' %}">Dashboard</a></li>
{% endif %}
<li role="menuitem"><a href="{% url 'storefront:customer-detail' user.pk %}">Orders</a></li>
<li role="menuitem"><a href="{% url 'account_logout' %}">Log Out</a></li>
</ul>
</div>
{% else %}
<span>
<a href="{% url 'account_login' %}">Log In</a>&emsp;|&emsp;<a href="{% url 'account_signup' %}">Sign Up</a>
</span>
{% endif %} {% endif %}
<span><a href="{% url 'account_logout' %}">Log Out</a></span> <a class="site__cart" href="{% url 'storefront:cart-detail' %}">
{% else %} <span class="cart__length">{{cart|length}}</span>
<span> <img class="cart__icon" src="{% static 'images/shopping_cart.svg' %}" alt="Shopping cart">
<a href="{% url 'account_login' %}">Log In</a>&emsp;|&emsp;<a href="{% url 'account_signup' %}">Sign Up</a> </a>
</span> </div>
{% endif %}
</div> </div>
<nav>
<a href="{% url 'storefront:product-list' %}">Shop</a>
{# <a href="">Wholesale</a> #}
<a href="">Subscribe</a>
<a href="">Cafe</a>
<a href="">Fair Trade</a>
<a href="{% url 'storefront:about' %}">About</a>
<a href="{% url 'storefront:contact' %}">Contact</a>
<a class="site__cart" href="{% url 'storefront:cart-detail' %}">
<span class="cart__length">{{cart|length}}</span>
<img class="cart__icon" src="{% static 'images/shopping_cart.svg' %}" alt="Shopping cart">
</a>
</nav>
</header> </header>
<main> <main>
{% block content %} {% block content %}