mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
More CSS all around
This commit is contained in:
parent
edd17e6630
commit
e7e82f2c99
9 changed files with 143 additions and 59 deletions
|
@ -1,5 +1,4 @@
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
|
||||||
import threading
|
import threading
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -137,7 +136,7 @@ class Delivery(Base):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_open(self):
|
def is_open(self):
|
||||||
return self.order_before > utils.utcnow()
|
return self.order_before > datetime.now()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_root(cls):
|
def get_root(cls):
|
||||||
|
|
|
@ -105,10 +105,6 @@ body {
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
background-color: var(--secondary-background-color);
|
background-color: var(--secondary-background-color);
|
||||||
}
|
}
|
||||||
header {
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3,
|
h3,
|
||||||
|
@ -138,6 +134,24 @@ a:hover {
|
||||||
color: #363636;
|
color: #363636;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
header section {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr auto;
|
||||||
|
}
|
||||||
|
header h1, nav {
|
||||||
|
line-height: 1rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
header h1 small {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
main a {
|
main a {
|
||||||
padding: 0 .1rem;
|
padding: 0 .1rem;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -217,7 +231,7 @@ input,
|
||||||
textarea {
|
textarea {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 1rem;
|
height: 2rem;
|
||||||
padding: .4rem .8rem;
|
padding: .4rem .8rem;
|
||||||
color: #50596c;
|
color: #50596c;
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
|
@ -225,7 +239,7 @@ textarea {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: .05rem solid #bbc;
|
border: .05rem solid #bbc;
|
||||||
border-radius: .1rem;
|
border-radius: .1rem;
|
||||||
transition: all .2s ease;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
|
@ -293,15 +307,15 @@ th.person {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
th.product {
|
th.product {
|
||||||
width: 15%;
|
width: 15rem;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
th.price {
|
th.price {
|
||||||
width: 5%;
|
width: 5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
th.amount {
|
th.amount {
|
||||||
width: 5%;
|
width: 5rem;
|
||||||
}
|
}
|
||||||
td.total,
|
td.total,
|
||||||
th.total {
|
th.total {
|
||||||
|
@ -316,6 +330,20 @@ tr:nth-child(1) {
|
||||||
tr:nth-child(1) * {
|
tr:nth-child(1) * {
|
||||||
color: #f1f1f1;
|
color: #f1f1f1;
|
||||||
}
|
}
|
||||||
|
article.order {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
table.order th.product {
|
||||||
|
width: inherit;
|
||||||
|
}
|
||||||
|
td.with-input {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
td.with-input input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
hr {
|
hr {
|
||||||
background-color: #dbdbdb;
|
background-color: #dbdbdb;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -355,6 +383,7 @@ hr {
|
||||||
}
|
}
|
||||||
.toggle-label {
|
.toggle-label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: #00d1b2;
|
||||||
}
|
}
|
||||||
.toggle-container {
|
.toggle-container {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -370,3 +399,37 @@ hr {
|
||||||
.toggle:checked ~ .toggle-container {
|
.toggle:checked ~ .toggle-container {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
ul.delivery {
|
||||||
|
padding: 10px
|
||||||
|
}
|
||||||
|
ul.delivery > li {
|
||||||
|
list-style: none;
|
||||||
|
padding: 20px 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
ul.delivery-head {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px , 1fr));
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
ul.delivery-head li {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
ul.delivery-head li i{
|
||||||
|
float: left;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
vertical-align: bottom;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
ul.toolbox {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(100px , 1fr));
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
ul.toolbox li {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
|
@ -14,10 +14,14 @@
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
{% if message %}
|
{% if message %}
|
||||||
<div class="notification {{ message[1] }}">{{ message[0] }}</div>
|
<section class="notification {{ message[1] }}">{{ message[0] }}</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h1><a href="/">Panio</a></h1>
|
<section>
|
||||||
<h5>Commandes groupées Épinamap</h5><a href="/livraison/new">Nouvelle livraison</a>
|
<h1><a href="/">Panio</a> <small>Les paniers piano d'Épinamap</small></h1>
|
||||||
|
<nav>
|
||||||
|
<a href="/livraison/new">Nouvelle livraison</a>
|
||||||
|
</nav>
|
||||||
|
</section>
|
||||||
</header>
|
</header>
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h3>{{ delivery.producer }}</h3>
|
<h3>{{ delivery.producer }}</h3>
|
||||||
<p><i class="icon-basket"></i> Description: {{ delivery.description }}</p>
|
{% include "includes/delivery_head.html" %}
|
||||||
<p><i class="icon-map-pin"></i> Lieu: {{ delivery.where }}</p>
|
|
||||||
<p><i class="icon-clock"></i> Date: {{ delivery.when }}</p>
|
|
||||||
<p><i class="icon-alarmclock"></i> Date limite de commande: {{ delivery.order_before.date() }}</p>
|
|
||||||
<table class="delivery">
|
<table class="delivery">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,13 +36,25 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<hr>
|
<hr>
|
||||||
<p><a href="/livraison/{{ delivery.id }}/edit">Modifier la livraison (admin)</a></p>
|
<ul class="toolbox">
|
||||||
<p><a href="/livraison/{{ delivery.id }}/rapport.xlsx">Générer un rapport</a></p>
|
<li>
|
||||||
<h3>Importer une commande</h3>
|
<a href="/livraison/{{ delivery.id }}/edit"><i class="icon-adjustments"></i> Modifier la livraison (admin)</a>
|
||||||
<p>Colonnes: ref*, wanted*</p>
|
</li>
|
||||||
<form action="/livraison/{{ delivery.id }}/importer/commande" method="post" enctype="multipart/form-data">
|
<li>
|
||||||
<input type="file" name="data">
|
<a href="/livraison/{{ delivery.id }}/rapport.xlsx"><i class="icon-download"></i> Rapport résumé</a>
|
||||||
<input type="email" name="email" placeholder="email">
|
</li>
|
||||||
<input type="submit" name="Importer une commande">
|
<li>
|
||||||
</form>
|
<label for="import-command" class="toggle-label"><i class="icon-paperclip"></i> Importer une commande</label>
|
||||||
|
<input type="checkbox" id="import-command" class="toggle">
|
||||||
|
<div class="toggle-container">
|
||||||
|
<label for="import-command" class="toggle-label">Fermer</label>
|
||||||
|
<p>Colonnes: ref*, wanted*</p>
|
||||||
|
<form action="/livraison/{{ delivery.id }}/importer/commande" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="file" name="data">
|
||||||
|
<input type="email" name="email" placeholder="email">
|
||||||
|
<input type="submit" name="Importer une commande">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
<h2>Livraisons à venir</h2>
|
||||||
|
<ul class="delivery">
|
||||||
{% for delivery in deliveries %}
|
{% for delivery in deliveries %}
|
||||||
<p>Producteur: {{ delivery.producer }}</p>
|
<li>
|
||||||
<p>Lieu: {{ delivery.where }}</p>
|
<h3><a href="/livraison/{{ delivery.id }}"><i class="icon-hotairballoon"></i> {{ delivery.producer }}</a></h3>
|
||||||
<p>Date: {{ delivery.when }}</p>
|
{% include "includes/delivery_head.html" %}
|
||||||
<form action="/livraison/{{ delivery.id }}/commander">
|
<!--form action="/livraison/{{ delivery.id }}/commander">
|
||||||
<label for="email">Commander</label>
|
<label for="email">Commander</label>
|
||||||
<input type="email" name="email" placeholder="Mon courriel">
|
<input type="email" name="email" placeholder="Mon courriel">
|
||||||
<input type="submit" value="Commander">
|
<input type="submit" value="Commander">
|
||||||
</form>
|
</form-->
|
||||||
<a href="/livraison/{{ delivery.id }}">Résumé de la livraison</a>
|
</li>
|
||||||
<hr>
|
<hr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
6
kaba/templates/includes/delivery_head.html
Normal file
6
kaba/templates/includes/delivery_head.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<ul class="delivery-head">
|
||||||
|
<li><i class="icon-basket"></i> {{ delivery.description }}</li>
|
||||||
|
<li><i class="icon-map-pin"></i> <strong>Lieu</strong> {{ delivery.where }}</li>
|
||||||
|
<li><i class="icon-clock"></i> <strong>Date de livraison</strong> {{ delivery.when }}</li>
|
||||||
|
<li><i class="icon-hourglass"></i> {% if delivery.is_open %}<strong>Date limite de commande</strong> {{ delivery.order_before.date() }}{% else %}<strong>Fermée</strong>{% endif %}</li>
|
||||||
|
</ul>
|
|
@ -1,14 +1,15 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<p>Producteur: {{ delivery.producer }} — Lieu: {{ delivery.where }} — Date: {{ delivery.when }} — Date limite de commande: {{ delivery.order_before }}</p>
|
<article class="order">
|
||||||
<p>Commande de «{{ person }}»</p>
|
<h3>{{ delivery.producer }} — Commande de «{{ person }}»</h3>
|
||||||
|
{% include "includes/delivery_head.html" %}
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<table>
|
<table class="order">
|
||||||
<tr><th>Produit</th><th>Prix</th><th>Quantité</th></tr>
|
<tr><th class="product">Produit</th><th class="price">Prix</th><th class="amount">Quantité</th></tr>
|
||||||
{% for product in delivery.products %}
|
{% for product in delivery.products %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ product.name }}
|
<th class="product">{{ product.name }}
|
||||||
<label for="toggleControl{{ loop.index }}" class="toggle-label">(Détails)</label>
|
<label for="toggleControl{{ loop.index }}" class="toggle-label">(Détails)</label>
|
||||||
<input type="checkbox" id="toggleControl{{ loop.index }}" class="toggle">
|
<input type="checkbox" id="toggleControl{{ loop.index }}" class="toggle">
|
||||||
<div class="toggle-container">
|
<div class="toggle-container">
|
||||||
|
@ -21,11 +22,12 @@
|
||||||
<label for="toggleControl{{ loop.index }}" class="toggle-label">Fermer</label>
|
<label for="toggleControl{{ loop.index }}" class="toggle-label">Fermer</label>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<td>{{ product.price }} €</td><td><input type="number" name="{{ product.ref }}" value="{{ order.get_quantity(product) }}"></td></tr>
|
<td>{{ product.price }} €</td><td class="with-input"><input type="number" name="{{ product.ref }}" value="{{ order.get_quantity(product) }}"></td></tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<p>Total: {{ order.total(delivery.products) if order else 0 }} €</p>
|
<p>Total: {{ order.total(delivery.products) if order else 0 }} €</p>
|
||||||
<input type="hidden" name="email" value="{{ person }}">
|
<input type="hidden" name="email" value="{{ person }}">
|
||||||
<input type="submit" value="Valider ma commande">
|
<input type="submit" value="Valider la commande">
|
||||||
</form>
|
</form>
|
||||||
|
</article>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import os
|
import os
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from roll.extensions import traceback
|
from roll.extensions import traceback
|
||||||
|
|
||||||
from kaba import app as kaba_app
|
from kaba import app as kaba_app
|
||||||
from kaba import config as kconfig
|
from kaba import config as kconfig
|
||||||
from kaba import utils
|
|
||||||
from kaba.models import Delivery, Person
|
from kaba.models import Delivery, Person
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,8 +30,8 @@ def app(): # Requested by Roll testing utilities.
|
||||||
def delivery():
|
def delivery():
|
||||||
return Delivery(
|
return Delivery(
|
||||||
producer="Andines",
|
producer="Andines",
|
||||||
when=utils.utcnow() + timedelta(days=10),
|
when=datetime.now() + timedelta(days=10),
|
||||||
order_before=utils.utcnow() + timedelta(days=7),
|
order_before=datetime.now() + timedelta(days=7),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kaba import utils
|
|
||||||
from kaba.models import Delivery, Product, Person, Order, ProductOrder
|
from kaba.models import Delivery, Product, Person, Order, ProductOrder
|
||||||
|
|
||||||
|
|
||||||
|
now = datetime.now
|
||||||
|
|
||||||
|
|
||||||
def test_can_create_delivery():
|
def test_can_create_delivery():
|
||||||
delivery = Delivery(
|
delivery = Delivery(producer="Andines", when=now(), order_before=now())
|
||||||
producer="Andines", when=utils.utcnow(), order_before=utils.utcnow()
|
|
||||||
)
|
|
||||||
assert delivery.producer == "Andines"
|
assert delivery.producer == "Andines"
|
||||||
assert delivery.where == "Marché de la Briche"
|
assert delivery.where == "Marché de la Briche"
|
||||||
assert delivery.when.year == utils.utcnow().year
|
assert delivery.when.year == now().year
|
||||||
assert delivery.id
|
assert delivery.id
|
||||||
|
|
||||||
|
|
||||||
def test_wrong_datetime_raise_valueerror():
|
def test_wrong_datetime_raise_valueerror():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Delivery(producer="Andines", order_before=utils.utcnow(), when="pouet")
|
Delivery(producer="Andines", order_before=now(), when="pouet")
|
||||||
|
|
||||||
|
|
||||||
def test_delivery_is_open_when_order_before_is_in_the_future(delivery):
|
def test_delivery_is_open_when_order_before_is_in_the_future(delivery):
|
||||||
delivery.order_before = utils.utcnow() + timedelta(hours=1)
|
delivery.order_before = now() + timedelta(hours=1)
|
||||||
assert delivery.is_open
|
assert delivery.is_open
|
||||||
delivery.order_before = utils.utcnow() - timedelta(hours=1)
|
delivery.order_before = now() - timedelta(hours=1)
|
||||||
assert not delivery.is_open
|
assert not delivery.is_open
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ def test_can_create_product():
|
||||||
def test_can_create_delivery_with_products():
|
def test_can_create_delivery_with_products():
|
||||||
delivery = Delivery(
|
delivery = Delivery(
|
||||||
producer="Andines",
|
producer="Andines",
|
||||||
when=utils.utcnow(),
|
when=now(),
|
||||||
order_before=utils.utcnow(),
|
order_before=now(),
|
||||||
products=[Product(name="Lait", ref="123", price=1.5)],
|
products=[Product(name="Lait", ref="123", price=1.5)],
|
||||||
)
|
)
|
||||||
assert len(delivery.products) == 1
|
assert len(delivery.products) == 1
|
||||||
|
|
Loading…
Reference in a new issue