aboutsummaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
Diffstat (limited to 'templates')
-rw-r--r--templates/balance.html107
-rw-r--r--templates/base.html91
-rw-r--r--templates/category/create.html51
-rw-r--r--templates/category/table.html38
-rw-r--r--templates/category/update.html85
-rw-r--r--templates/error.html17
-rw-r--r--templates/income/create.html89
-rw-r--r--templates/income/table.html55
-rw-r--r--templates/income/update.html117
-rw-r--r--templates/login.html29
-rw-r--r--templates/macros/paging.html55
-rw-r--r--templates/payment/create.html120
-rw-r--r--templates/payment/table.html128
-rw-r--r--templates/payment/update.html144
-rw-r--r--templates/report/list.j214
-rw-r--r--templates/report/report.j250
-rw-r--r--templates/statistics.html29
17 files changed, 1219 insertions, 0 deletions
diff --git a/templates/balance.html b/templates/balance.html
new file mode 100644
index 0000000..15da854
--- /dev/null
+++ b/templates/balance.html
@@ -0,0 +1,107 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Équilibre
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ {% if exceeding_payers %}
+ <ul class="g-Balance__ExceedingPayers">
+ {% for exceeding_payer in exceeding_payers %}
+ <li class="g-Balance__ExceedingPayer">
+ {{ exceeding_payer.0 }} : +{{ exceeding_payer.1 | euros() }}
+ </li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ <p class="g-Paragraph">
+ Les paiements sont équilibrés.
+ </p>
+ {% endif %}
+
+ {% if incomes_from %}
+ <h1 class="g-Title">
+ Revenus
+ </h1>
+
+ <div class="g-Table">
+ <div class="g-Table__Row g-Table__Row--Header">
+ <span class="g-Table__Cell"></span>
+ <span class="g-Table__Cell">Montant</span>
+ <span class="g-Table__Cell">Part</span>
+ </div>
+ {% for user_income in user_incomes %}
+ <div class="g-Table__Row">
+ <span class="g-Table__Cell">
+ {{ user_income.0 }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {{ user_income.1 | euros() }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {% if total_income > 0 %}
+ {{ user_income.1 / total_income * 100 | round() }} %
+ {% else %}
+ –
+ {% endif %}
+ </span>
+ </div>
+ {% endfor %}
+ <div class="g-Table__Row">
+ <span class="g-Table__Cell">
+ Total
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {{ total_income | euros() }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ 100 %
+ </span>
+ </div>
+ </div>
+ {% endif %}
+
+ <h1 class="g-Title">
+ Paiements
+ </h1>
+
+ <div class="g-Table">
+ <div class="g-Table__Row g-Table__Row--Header">
+ <span class="g-Table__Cell"></span>
+ <span class="g-Table__Cell">Montant</span>
+ <span class="g-Table__Cell">Part</span>
+ </div>
+ {% for user_payment in user_payments %}
+ <div class="g-Table__Row">
+ <span class="g-Table__Cell">
+ {{ user_payment.0 }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {{ user_payment.1 | euros() }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {% if total_payments > 0 %}
+ {{ user_payment.1 / total_payments * 100 | round() }} %
+ {% else %}
+ –
+ {% endif %}
+ </span>
+ </div>
+ {% endfor %}
+ <div class="g-Table__Row">
+ <span class="g-Table__Cell">
+ Total
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {{ total_payments | euros() }}
+ </span>
+ <span class="g-Table__Cell g-Table__NumericCell">
+ 100 %
+ </span>
+ </div>
+ </div>
+ </div>
+
+{% endblock main %}
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..f403d41
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html lang="fr">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Budget — {% block title %}{% endblock title %}</title>
+ <link rel="stylesheet" href="{{ assets | get(key="main.css") }}" />
+ <link rel="icon" href="{{ assets | get(key="icon.png") }}">
+ </head>
+
+ <body>
+
+ <header class="g-Header">
+
+ <div class="g-Header__Primary">
+ <div class="g-Header__Title">Budget</div>
+ {% if connected_user %}
+ <form action="/logout" method="POST">
+ {{ connected_user.name }}
+ <input class="g-Header__Logout" type="submit" value="(Déconnexion)" />
+ </form>
+ {% endif %}
+ </div>
+
+ {% if connected_user %}
+ <div class="g-Header__Secondary">
+
+ <a
+ href="/"
+ class="
+ g-Header__Link
+ {% if header == "Payments" %} g-Header__Link--Current {% endif %}
+ "
+ >
+ Paiements
+ </a>
+
+ <a
+ href="/incomes"
+ class="
+ g-Header__Link
+ {% if header == "Incomes" %} g-Header__Link--Current {% endif %}
+ "
+ >
+ Revenus
+ </a>
+
+ <a
+ href="/categories"
+ class="
+ g-Header__Link
+ {% if header == "Categories" %} g-Header__Link--Current {% endif %}
+ "
+ >
+ Catégories
+ </a>
+
+ <a
+ href="/balance"
+ class="
+ g-Header__Link
+ {% if header == "Balance" %} g-Header__Link--Current {% endif %}
+ "
+ >
+ Équilibre
+ </a>
+
+ <a
+ href="/statistics"
+ class="
+ g-Header__Link
+ {% if header == "Statistics" %} g-Header__Link--Current {% endif %}
+ "
+ >
+ Statistiques
+ </a>
+
+ </div>
+ {% endif %}
+
+ </header>
+
+ <main class="g-Main">
+ {% block main %}{% endblock main %}
+ </main>
+
+ <script src="{{ assets | get(key="main.js") }}">
+ </script>
+
+ </body>
+</html>
diff --git a/templates/category/create.html b/templates/category/create.html
new file mode 100644
index 0000000..e206898
--- /dev/null
+++ b/templates/category/create.html
@@ -0,0 +1,51 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Nouvelle catégorie
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a class="g-Link g-Media__Large" href="/categories">
+ Retour aux categories
+ </a>
+ </p>
+
+ <form class="g-Form" action="/category/create" method="POST">
+ <h1 class="g-H1">
+ Nouvelle catégorie
+ </h1>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ <label class="g-Form__Label" for="name">Nom</label>
+ <input
+ name="name"
+ class="g-Form__Input"
+ id="name"
+ value="{{ form.name | default(value="") }}"
+ required
+ {% if not form %} autofocus {% endif %}
+ />
+
+ <label class="g-Form__Label" for="color">Couleur</label>
+ <input
+ name="color"
+ type="color"
+ class="g-Form__Input g-Form__InputColor"
+ id="color"
+ value="{{ form.color | default(value="") }}"
+ required
+ />
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Créer" />
+ </div>
+ </form>
+ </div>
+
+{% endblock main %}
diff --git a/templates/category/table.html b/templates/category/table.html
new file mode 100644
index 0000000..896304a
--- /dev/null
+++ b/templates/category/table.html
@@ -0,0 +1,38 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Catégories
+{% endblock title %}
+
+{% block main %}
+
+ <div class="g-Paragraph g-Payments__Header">
+ <a class="g-Button__Validate" href="/category">Nouveau</a>
+ </div>
+
+ {% if not categories %}
+
+ <div class="g-Payments__NoResults">
+ Il n’y a aucune catégorie.
+ </div>
+
+ {% else %}
+
+ <div class="g-Table">
+ {% for category in categories %}
+ <a
+ class="g-Table__Row {% if highlight == category.id %} g-Table__Row--Highlight {% endif %}"
+ href="/category/{{ category.id }}"
+ >
+ <span
+ class="g-Table__Cell"
+ style="color: {{ category.color }}"
+ >
+ {{ category.name }}
+ </span>
+ </a>
+ {% endfor %}
+ </div>
+
+ {% endif %}
+{% endblock main %}
diff --git a/templates/category/update.html b/templates/category/update.html
new file mode 100644
index 0000000..a4c1481
--- /dev/null
+++ b/templates/category/update.html
@@ -0,0 +1,85 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Catégorie {{ id }}
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a class="g-Link g-Media__Large" href="/categories">
+ Retour aux catégories
+ </a>
+ </p>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ {% if not category %}
+
+ La catégorie n’a pas été trouvée.
+
+ {% else %}
+
+ <form
+ class="g-Form"
+ action="/category/{{ category.id }}/update"
+ method="POST"
+ >
+ <h1 class="g-H1">Modification</h1>
+
+ <label class="g-Form__Label" for="name">Nom</label>
+ <input
+ name="name"
+ class="g-Form__Input"
+ id="name"
+ value="{{ form.name | default(value=category.name) }}"
+ required
+ />
+
+ <label class="g-Form__Label" for="color">Couleur</label>
+ <input
+ name="color"
+ type="color"
+ class="g-Form__Input g-Form__InputColor"
+ id="color"
+ value="{{ form.color | default(value=category.color) }}"
+ required
+ />
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Modifier" />
+ </div>
+ </form>
+
+ <form
+ class="g-Form"
+ action="/category/{{ category.id }}/delete"
+ method="POST"
+ >
+ <h1 class="g-H1">Suppression</h1>
+
+ {% if is_category_used %}
+ <p>
+ La catégorie ne peut pas être supprimée car elle est actuellement
+ utilisée.
+ </p>
+ {% else %}
+ <label class="g-Form__Label" for="remove-input">
+ Veuillez recopier le nom de la catégorie : « {{ category.name }} ».
+ </label>
+
+ <input name="remove-input" class="g-Form__Input" id="remove-input" data-name="{{ category.name }}" />
+
+ <div>
+ <input class="g-Button__Danger" type="submit" value="Supprimer" id="remove-button" disabled />
+ </div>
+ {% endif %}
+ </form>
+
+ {% endif %}
+ </div>
+
+{% endblock main %}
diff --git a/templates/error.html b/templates/error.html
new file mode 100644
index 0000000..b3049a9
--- /dev/null
+++ b/templates/error.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block title %}
+ {{ title }}
+{% endblock title %}
+
+{% block main %}
+ <p class="g-Paragraph">
+ {{ message }}
+ </p>
+
+ <p class="g-Paragraph">
+ <a href="/" class="g-Link">
+ Retour à l’accueil
+ </a>
+ </p>
+{% endblock main %}
diff --git a/templates/income/create.html b/templates/income/create.html
new file mode 100644
index 0000000..b74dddd
--- /dev/null
+++ b/templates/income/create.html
@@ -0,0 +1,89 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Nouveau revenu
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a
+ class="g-Link g-Media__Large"
+ href="/incomes?page={{ query.page | default(value=1) }}"
+ >
+ Retour aux revenus
+ </a>
+ </p>
+
+ <form
+ class="g-Form"
+ action="/income/create?page={{ query.page | default(value=1) }}"
+ method="POST"
+ >
+ <h1 class="g-H1">
+ Nouveau revenu
+ </h1>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ <label class="g-Form__Label" for="amount">Montant</label>
+ <input
+ name="amount"
+ type="number"
+ class="g-Form__Input"
+ id="amount"
+ value="{{ form.amount | default(value="") }}"
+ required
+ {% if not form %} autofocus {% endif %}
+ />
+
+ {% set user_id = form.user_id | default(value="" ~ connected_user.id) %}
+
+ <label class="g-Form__Label" for="user_id">Personne</label>
+ <select name="user_id" id="user_id" class="g-Form__Select" required>
+ {% for user in users %}
+ <option
+ value="{{ user.id }}"
+ {% if "" ~ user.id == user_id %} selected {% endif %}
+ >
+ {{ user.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set month_index = form.month | default(value="" ~ current_month) %}
+
+ <label class="g-Form__Label" for="month">Mois</label>
+ <select name="month" id="month" class="g-Form__Select" required>
+ {% for month in months %}
+ <option
+ value="{{ loop.index }}"
+ {% if "" ~ loop.index == month_index %}
+ selected
+ {% endif %}
+ >
+ {{ month }}
+ </option>
+ {% endfor %}
+ </select>
+
+ <label class="g-Form__Label" for="year">Année</label>
+ <input
+ name="year"
+ type="number"
+ class="g-Form__Input"
+ id="year"
+ value="{{ form.year | default(value=now() | date(format="%Y")) }}"
+ required
+ />
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Créer" />
+ </div>
+ </form>
+ </div>
+
+{% endblock main %}
diff --git a/templates/income/table.html b/templates/income/table.html
new file mode 100644
index 0000000..efd82a7
--- /dev/null
+++ b/templates/income/table.html
@@ -0,0 +1,55 @@
+{% import "macros/paging.html" as paging %}
+
+{% extends "base.html" %}
+
+{% block title %}
+ Revenus
+{% endblock title %}
+
+{% block main %}
+
+ <div class="g-Paragraph g-Payments__Header">
+ <a
+ class="g-Button__Validate"
+ href="/income?page={{ page | default(value=1) }}"
+ >
+ Nouveau
+ </a>
+ </div>
+
+ {% if not incomes %}
+
+ <div class="g-Payments__NoResults">
+ Il n’y a aucun revenu.
+ </div>
+
+ {% else %}
+
+ <div class="g-Table">
+ <div class="g-Table__Row g-Table__Row--Header">
+ <span class="g-Table__Cell">Montant</span>
+ <span class="g-Table__Cell">Personne</span>
+ <span class="g-Table__Cell">Mois</span>
+ </div>
+ {% for income in incomes %}
+ <a
+ class="g-Table__Row {% if highlight == income.id %} g-Table__Row--Highlight {% endif %}"
+ href="/income/{{ income.id }}?page={{ page | default(value=1) }}"
+ >
+ <span class="g-Table__Cell g-Table__NumericCell">
+ {{ income.amount | euros() }}
+ </span>
+ <span class="g-Table__Cell">{{ income.user }}</span>
+ <span class="g-Table__Cell">{{ income.date }}</span>
+ </a>
+ {% endfor %}
+ </div>
+
+ {{ paging::paging(
+ url="/incomes",
+ page=page,
+ max_page=max_page
+ ) }}
+
+ {% endif %}
+{% endblock main %}
diff --git a/templates/income/update.html b/templates/income/update.html
new file mode 100644
index 0000000..6dd649a
--- /dev/null
+++ b/templates/income/update.html
@@ -0,0 +1,117 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Revenu {{ id }}
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a
+ class="g-Link g-Media__Large"
+ href="/incomes?page={{ query.page | default(value=1) }}"
+ >
+ Retour aux revenus
+ </a>
+ </p>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ {% if not income %}
+
+ Le revenu n’a pas été trouvé.
+
+ {% else %}
+
+ <form
+ class="g-Form"
+ action="/income/{{ income.id }}/update"
+ method="POST"
+ >
+ <h1 class="g-H1">Modification</h1>
+
+ <label class="g-Form__Label" for="amount">Montant</label>
+ <input
+ name="amount"
+ type="number"
+ class="g-Form__Input"
+ id="amount"
+ value="{{ form.amount | default(value=income.amount) }}"
+ required
+ />
+
+ {% set user_id = form.user_id | default(value="" ~ income.user_id) %}
+
+ <label class="g-Form__Label" for="user_id">Personne</label>
+ <select name="user_id" id="user_id" class="g-Form__Select" required>
+ {% for user in users %}
+ <option
+ value="{{ user.id }}"
+ {% if "" ~ user.id == user_id %} selected {% endif %}
+ >
+ {{ user.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set month_index = form.month | default(value="" ~ income.month) %}
+
+ <label class="g-Form__Label" for="month">Mois</label>
+ <select name="month" id="month" class="g-Form__Select" required>
+ {% for month in months %}
+ <option
+ value="{{ loop.index }}"
+ {% if "" ~ loop.index == month_index %} selected {% endif %}
+ >
+ {{ month }}
+ </option>
+ {% endfor %}
+ </select>
+
+ <label class="g-Form__Label" for="year">Année</label>
+ <input
+ name="year"
+ type="number"
+ class="g-Form__Input"
+ id="year"
+ value="{{ form.year | default(value=income.year) }}"
+ required
+ />
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Modifier" />
+ </div>
+ </form>
+
+ <form
+ class="g-Form"
+ action="/income/{{ income.id }}/delete"
+ method="POST"
+ >
+ <h1 class="g-H1">Suppression</h1>
+
+ {% if is_category_used %}
+ <p>
+ La catégorie ne peut pas être supprimée car elle est actuellement
+ utilisée.
+ </p>
+ {% else %}
+ <label class="g-Form__Label" for="remove-input">
+ Veuillez recopier le montant du revenu : « {{ income.amount }} ».
+ </label>
+
+ <input name="remove-input" class="g-Form__Input" id="remove-input" data-name="{{ income.amount }}" />
+
+ <div>
+ <input class="g-Button__Danger" type="submit" value="Supprimer" id="remove-button" disabled />
+ </div>
+ {% endif %}
+ </form>
+
+ {% endif %}
+ </div>
+
+{% endblock main %}
diff --git a/templates/login.html b/templates/login.html
new file mode 100644
index 0000000..fd4cfe9
--- /dev/null
+++ b/templates/login.html
@@ -0,0 +1,29 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Connexion
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <form class="g-Login g-Form" action="/login" method="POST">
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ <label class="g-Form__Label" for="email">Email</label>
+ <input name="email" class="g-Form__Input" id="email" required autofocus />
+
+ <label class="g-Form__Label" for="password">Mot de passe</label>
+ <input name="password" type="password" class="g-Form__Input" id="password" required />
+
+ <div>
+ <input class="g-Login__Button g-Button__Validate" type="submit" value="Connexion" />
+ </div>
+
+ </form>
+ </div>
+
+{% endblock main %}
diff --git a/templates/macros/paging.html b/templates/macros/paging.html
new file mode 100644
index 0000000..59ba617
--- /dev/null
+++ b/templates/macros/paging.html
@@ -0,0 +1,55 @@
+{% macro paging(url, page, max_page) %}
+ {% if url is containing("?") %}
+ {% set sign = "&" %}
+ {% else %}
+ {% set sign = "?" %}
+ {% endif %}
+
+ <div class="g-Paging">
+ {% if page > 1 %}
+ <a
+ class="g-Paging__Link g-Paging__Link--Active"
+ href="{{ url }}"
+ >
+ ❬❬
+ </a>
+ <a
+ class="g-Paging__Link g-Paging__Link--Active"
+ href="{{ url }}{{ sign }}page={{ page - 1 }}"
+ >
+ ❬
+ </a>
+ {% else %}
+ <span class="g-Paging__Link">
+ ❬❬
+ </span>
+ <span class="g-Paging__Link">
+ ❬
+ </span>
+ {% endif %}
+
+ {{ page }} / {{ max_page }}
+
+ {% if page < max_page %}
+ <a
+ class="g-Paging__Link g-Paging__Link--Active"
+ href="{{ url }}{{ sign }}page={{ page + 1 }}"
+ >
+ ❭
+ </a>
+ <a
+ class="g-Paging__Link g-Paging__Link--Active"
+ href="{{ url }}{{ sign }}page={{ max_page }}"
+ >
+ ❭❭
+ </a>
+ {% else %}
+ <span class="g-Paging__Link">
+ ❭
+ </span>
+ <span class="g-Paging__Link">
+ ❭❭
+ </span>
+ {% endif %}
+ </div>
+{% endmacro paging %}
diff --git a/templates/payment/create.html b/templates/payment/create.html
new file mode 100644
index 0000000..aea6fcd
--- /dev/null
+++ b/templates/payment/create.html
@@ -0,0 +1,120 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Nouveau paiement
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a
+ class="g-Link g-Media__Large"
+ href="/{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency
+ ) }}"
+ >
+ Retour aux paiements
+ </a>
+ </p>
+
+ <form class="g-Form" action="/payment/create" method="POST">
+ <h1 class="g-H1">
+ Nouveau paiement
+ {% if query.frequency != "Monthly" %}
+ ponctuel
+ {% else %}
+ mensuel
+ {% endif %}
+ </h1>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ <label class="g-Form__Label" for="name">Nom</label>
+ <input
+ name="name"
+ class="g-Form__Input"
+ id="name"
+ value="{{ form.name | default(value="") }}"
+ required
+ {% if not form %} autofocus {% endif %}
+ />
+
+ <label class="g-Form__Label" for="cost">Coût</label>
+ <input
+ name="cost"
+ type="number"
+ class="g-Form__Input"
+ id="cost"
+ value="{{ form.cost | default(value="") }}"
+ required
+ />
+
+ {% set user_id = form.user_id | default(value="" ~ connected_user.id) %}
+
+ <label class="g-Form__Label" for="user_id">Personne</label>
+ <select name="user_id" id="user_id" class="g-Form__Select" required>
+ {% for user in users %}
+ <option
+ value="{{ user.id }}"
+ {% if "" ~ user.id == user_id %}
+ selected
+ {% endif %}
+ >
+ {{ user.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set category_id = form.category_id | default(value="") %}
+
+ <label class="g-Form__Label" for="category_id">Catégorie</label>
+ <select name="category_id" id="category_id" class="g-Form__Select" required>
+ {% for category in categories %}
+ <option
+ value="{{ category.id }}"
+ style="color: {{ category.color }}"
+ {% if "" ~ category.id == category_id %} selected {% endif %}
+ >
+ {{ category.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set date = form.date | default(value=now() | date(format="%Y-%m-%d")) %}
+
+ {% if query.frequency != "Monthly" %}
+ <label class="g-Form__Label" for="date">Date</label>
+ <input
+ name="date"
+ type="date"
+ class="g-Form__Input"
+ id="date"
+ value="{{ date }}"
+ required
+ />
+ {% else %}
+ <input
+ name="date"
+ type="hidden"
+ value="{{ date }}"
+ />
+ {% endif %}
+
+ <input
+ type="hidden"
+ name="frequency"
+ value="{{ query.frequency | default(value="Punctual") }}"
+ />
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Créer" />
+ </div>
+ </form>
+ </div>
+
+{% endblock main %}
diff --git a/templates/payment/table.html b/templates/payment/table.html
new file mode 100644
index 0000000..19b56b4
--- /dev/null
+++ b/templates/payment/table.html
@@ -0,0 +1,128 @@
+{% import "macros/paging.html" as paging %}
+
+{% extends "base.html" %}
+
+{% block title %}
+ Paiements
+{% endblock title %}
+
+{% block main %}
+
+ <div class="g-Paragraph g-Payments__Header">
+ <div class="g-Payments__FrequenciesAndSearch">
+ <div class="g-Payments__Frequencies">
+ {% if query.frequency == "Monthly" %}
+ <a
+ class="g-Payments__Frequency g-Link"
+ href="/{{ payments_params(frequency="Punctual") }}"
+ >
+ Ponctuels
+ </a>
+ /
+ <span class="g-Payments__Frequency g-Payments__Frequency--Selected">
+ Mensuels
+ </span>
+ {% else %}
+ <span class="g-Payments__Frequency g-Payments__Frequency--Selected">
+ Ponctuels
+ </span>
+ /
+ <a
+ class="g-Payments__Frequency g-Link"
+ href="/{{ payments_params(frequency="Monthly") }}"
+ >
+ Mensuels
+ </a>
+ {% endif %}
+ </div>
+
+ {% if query.frequency != "Monthly" %}
+ <form action="/" method="GET" class="g-Payments__Search">
+ <input
+ type="search"
+ name="search"
+ class="g-Form__Input g-Payments__SearchInput"
+ value="{{ query.search }}"
+ />
+ <input type="submit" class="g-Button__Search" value="🔍">
+ </form>
+ {% endif %}
+ </div>
+
+ <a
+ class="g-Button__Validate g-Payments__New"
+ href="/payment{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency
+ ) }}"
+ >
+ Nouveau
+ </a>
+ </div>
+
+ {% if not payments %}
+
+ <div class="g-Payments__NoResults">
+ Aucun paiement ne correspond à votre recherche.
+ </div>
+
+ {% else %}
+
+ <div class="g-Paragraph">
+ {{ count | numeric }} paiement{{ count | pluralize }} comptabilisant {{ total_cost | euros() }}.
+ </div>
+
+ <div class="g-Table">
+ <div class="g-Table__Row g-Table__Row--Header">
+ <span class="g-Table__Cell">Nom</span>
+ <span class="g-Table__Cell">Coût</span>
+ <span class="g-Table__Cell">Personne</span>
+ <span class="g-Media__Large g-Table__Cell">Catégorie</span>
+ {% if query.frequency != "Monthly" %}
+ <span class="g-Table__Cell">Date</span>
+ {% endif %}
+ </div>
+ {% for payment in payments %}
+ <a
+ class="g-Table__Row {% if query.highlight == payment.id %} g-Table__Row--Highlight {% endif %}"
+ href="/payment/{{ payment.id }}{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency
+ ) }}"
+ >
+ <span class="g-Table__Cell">{{ payment.name }}</span>
+ <span class="
+ g-Table__Cell
+ g-Table__NumericCell
+ {% if payment.cost < 0 %} g-Payments__Refund {% endif %}
+ ">
+ {{ payment.cost | euros() }}
+ </span>
+ <span class="g-Table__Cell">{{ payment.user }}</span>
+ <span class="g-Table__Cell g-Media__Large">
+ <span style="color: {{ payment.category_color }}">
+ {{ payment.category_name }}
+ </span>
+ </span>
+ {% if query.frequency != "Monthly" %}
+ <span class="g-Table__Cell">
+ {{ payment.date }}
+ </span>
+ {% endif %}
+ </a>
+ {% endfor %}
+ </div>
+
+ {{ paging::paging(
+ url="/" ~ payments_params(
+ search=query.search,
+ frequency=query.frequency
+ ),
+ page=page,
+ max_page=max_page
+ ) }}
+
+ {% endif %}
+{% endblock main %}
diff --git a/templates/payment/update.html b/templates/payment/update.html
new file mode 100644
index 0000000..25e6915
--- /dev/null
+++ b/templates/payment/update.html
@@ -0,0 +1,144 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Paiement {{ id }}
+{% endblock title %}
+
+{% block main %}
+
+ <div>
+ <p class="g-Paragraph">
+ <a
+ class="g-Link g-Media__Large"
+ href="/{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency
+ ) }}"
+ >
+ Retour aux paiements
+ </a>
+ </p>
+
+ {% if error %}
+ <div class="g-Form__Error">{{ error }}</div>
+ {% endif %}
+
+ {% if not payment %}
+
+ Le paiement n’a pas été trouvé.
+
+ {% else %}
+
+ <form
+ class="g-Form"
+ action="/payment/{{ payment.id }}/update{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency,
+ highlight=query.highlight
+ ) }}"
+ method="POST"
+ >
+ <h1 class="g-H1">Modification</h1>
+
+ <label class="g-Form__Label" for="name">Nom</label>
+ <input
+ name="name"
+ class="g-Form__Input"
+ id="name"
+ value="{{ form.name | default(value=payment.name) }}"
+ required
+ />
+
+ <label class="g-Form__Label" for="cost">Coût</label>
+ <input
+ name="cost"
+ type="number"
+ class="g-Form__Input"
+ id="cost"
+ value="{{ form.cost | default(value=payment.cost) }}"
+ required
+ />
+
+ {% set user_id = form.user_id | default(value="" ~ payment.user_id) %}
+
+ <label class="g-Form__Label" for="user_id">Personne</label>
+ <select name="user_id" id="user_id" class="g-Form__Select" required>
+ {% for user in users %}
+ <option
+ value="{{ user.id }}"
+ {% if "" ~ user.id == user_id %} selected {% endif %}
+ >
+ {{ user.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set category_id = form.category_id | default(value="" ~ payment.category_id) %}
+
+ <label class="g-Form__Label" for="category_id">Catégorie</label>
+ <select name="category_id" id="category_id" class="g-Form__Select" required>
+ {% for category in categories %}
+ <option
+ value="{{ category.id }}"
+ style="color: {{ category.color }}"
+ {% if "" ~ category.id == category_id %} selected {% endif %}
+ >
+ {{ category.name }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {% set date = form.date | default(value=payment.date) %}
+
+ {% if payment.frequency == "Punctual" %}
+ <label class="g-Form__Label" for="date">Date</label>
+ <input
+ name="date"
+ type="date"
+ class="g-Form__Input"
+ id="date"
+ value="{{ date }}"
+ required
+ />
+ {% else %}
+ <input
+ name="date"
+ type="hidden"
+ value="{{ date }}"
+ />
+ {% endif %}
+
+ <div>
+ <input class="g-Button__Validate" type="submit" value="Modifier" />
+ </div>
+ </form>
+
+ <form
+ class="g-Form"
+ action="/payment/{{ payment.id }}/delete{{ payments_params(
+ page=query.page,
+ search=query.search,
+ frequency=query.frequency,
+ highlight=query.highlight
+ ) }}"
+ method="POST"
+ >
+ <h1 class="g-H1">Suppression</h1>
+
+ <label class="g-Form__Label" for="remove-input">
+ Veuillez recopier le nom du paiement : « {{ payment.name }} ».
+ </label>
+
+ <input name="remove-input" class="g-Form__Input" id="remove-input" data-name="{{ payment.name }}" />
+
+ <div>
+ <input class="g-Button__Danger" type="submit" value="Supprimer" id="remove-button" disabled />
+ </div>
+ </form>
+
+ {% endif %}
+ </div>
+
+{% endblock main %}
diff --git a/templates/report/list.j2 b/templates/report/list.j2
new file mode 100644
index 0000000..ef53244
--- /dev/null
+++ b/templates/report/list.j2
@@ -0,0 +1,14 @@
+{% macro list(resource, action, xs) -%}
+
+{% if xs -%}
+
+ {% set s = xs | length | pluralize -%}
+
+ {{ xs | length }} {{ resource }}{{ s }} {{ action }}{{ s }} :
+
+ {% for x in xs -%}
+ - {{ x.date }} {{ x.name }} {{ x.amount | euros() }}
+ {% endfor %}
+{% endif -%}
+
+{% endmacro paging %}
diff --git a/templates/report/report.j2 b/templates/report/report.j2
new file mode 100644
index 0000000..d36f3ce
--- /dev/null
+++ b/templates/report/report.j2
@@ -0,0 +1,50 @@
+{% import "report/list.j2" as list %}
+
+{% if exceeding_payers -%}
+
+ Équilibre :
+
+ {% for exceeding_payer in exceeding_payers -%}
+ - {{ exceeding_payer.0 }} : +{{ exceeding_payer.1 | euros() }}
+ {% endfor %}
+{% else -%}
+
+ Les paiements sont équilibrés.
+
+{% endif %}{#
+
+#}{{ list::list(
+ resource="paiement",
+ action="créé",
+ xs=payments | filter(attribute="action", value="Created")
+) }}{#
+
+#}{{ list::list(
+ resource="paiement",
+ action="modifié",
+ xs=payments | filter(attribute="action", value="Updated")
+) }}{#
+
+#}{{ list::list(
+ resource="paiement",
+ action="supprimé",
+ xs=payments | filter(attribute="action", value="Deleted")
+) }}{#
+
+#}{{ list::list(
+ resource="revenu",
+ action="créé",
+ xs=incomes | filter(attribute="action", value="Created")
+) }}{#
+
+#}{{ list::list(
+ resource="revenu",
+ action="modifié",
+ xs=incomes | filter(attribute="action", value="Updated")
+) }}{#
+
+#}{{ list::list(
+ resource="revenu",
+ action="supprimé",
+ xs=incomes | filter(attribute="action", value="Deleted")
+) }}
diff --git a/templates/statistics.html b/templates/statistics.html
new file mode 100644
index 0000000..badbc6d
--- /dev/null
+++ b/templates/statistics.html
@@ -0,0 +1,29 @@
+{% extends "base.html" %}
+
+{% block title %}
+ Statistiques
+{% endblock title %}
+
+{% block main %}
+
+ <div class="g-Chart">
+ <canvas id="g-Chart__Canvas">
+ </canvas>
+ </div>
+
+ <div id="categories" hidden>
+ {{ json_categories }}
+ </div>
+
+ <div id="incomes" hidden>
+ {{ json_incomes }}
+ </div>
+
+ <div id="payments" hidden>
+ {{ json_payments }}
+ </div>
+
+ <script src="{{ assets | get(key="chart.js") }}">
+ </script>
+
+{% endblock main %}