feat: another batch of fixes

This commit is contained in:
Herculino Trotta
2025-11-04 10:29:40 -03:00
parent 9ade58a003
commit 0a4d4c12b9
18 changed files with 391 additions and 324 deletions
@@ -2,8 +2,8 @@
{% load i18n %} {% load i18n %}
<div> <div>
<div class="hidden lg:grid lg:grid-cols-7 gap-4 lg:gap-0 bg-base-300"> <div class="hidden lg:grid lg:grid-cols-7 gap-4 lg:gap-0 bg-base-200">
<div class="border-l border-t border-b border-base-100 p-2 text-center"> <div class="border-l border-t border-b border-base-300 p-2 text-center">
{% translate 'MON' %} {% translate 'MON' %}
</div> </div>
<div class="border-t border-b border-base-300 p-2 text-center"> <div class="border-t border-b border-base-300 p-2 text-center">
@@ -28,7 +28,7 @@
<div class="grid grid-cols-1 grid-rows-1 lg:grid-cols-7 lg:grid-rows-6 gap-4 lg:gap-0"> <div class="grid grid-cols-1 grid-rows-1 lg:grid-cols-7 lg:grid-rows-6 gap-4 lg:gap-0">
{% for date in dates %} {% for date in dates %}
{% if date %} {% if date %}
<div class="card bg-base-200 h-full hover:bg-base-300! border-[1px] border-base-content/30 rounded-none card-border {% if not date.transactions %}hidden! lg:flex!{% endif %}{% if today == date.date %} card-border border-2 border-primary{% endif %} cursor-pointer" role="button" <div class="card bg-base-100 h-full hover:bg-base-200! border border-base-content/30 rounded-none {% if not date.transactions %}hidden! lg:flex!{% endif %}{% if today == date.date %} border-2 border-primary{% endif %} cursor-pointer" role="button"
hx-get="{% url 'calendar_transactions_list' day=date.date.day month=date.date.month year=date.date.year %}" hx-get="{% url 'calendar_transactions_list' day=date.date.day month=date.date.month year=date.date.year %}"
hx-target="#persistent-generic-offcanvas-left"> hx-target="#persistent-generic-offcanvas-left">
<div class="card-header border-0 bg-transparent text-end flex justify-between p-2 w-full"> <div class="card-header border-0 bg-transparent text-end flex justify-between p-2 w-full">
@@ -62,7 +62,7 @@
</div> </div>
</div> </div>
{% else %} {% else %}
<div class="hidden! lg:block! card bg-base-100 h-full rounded-none"></div> <div class="hidden! lg:block! card bg-base-300 h-full rounded-none"></div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
+1 -1
View File
@@ -3,7 +3,7 @@
{% if not divless %} {% if not divless %}
<div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}"> <div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}">
{% endif %} {% endif %}
<span class="amount{% if color == 'grey' or color == "gray" %} text-base-content/50{% elif color == 'green' %} text-success {% elif color == 'red' %} text-error{% endif %} font-medium {{ custom_class }}" <span class="amount{% if color == 'grey' or color == "gray" %} text-exchange-rate{% elif color == 'green' %} text-income {% elif color == 'red' %} text-expense{% endif %} font-medium {{ custom_class }}"
data-original-value="{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places %}" data-original-value="{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places %}"
data-amount="{{ amount|floatformat:"-40u" }}"> data-amount="{{ amount|floatformat:"-40u" }}">
</span><span>{{ slot }}</span> </span><span>{{ slot }}</span>
+6 -5
View File
@@ -35,7 +35,7 @@
{% endif %} {% endif %}
</div> </div>
<div <div
class="lg:flex-1 w-full {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}brightness-80{% endif %}"> class="lg:flex-1 w-full {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}opacity-70{% endif %}">
{# Date#} {# Date#}
<div class="flex flex-wrap mb-2 lg:mb-1 text-base-content/70"> <div class="flex flex-wrap mb-2 lg:mb-1 text-base-content/70">
<div class="w-auto pe-1"><i class="fa-solid fa-calendar fa-fw mr-1 fa-xs"></i></div> <div class="w-auto pe-1"><i class="fa-solid fa-calendar fa-fw mr-1 fa-xs"></i></div>
@@ -106,7 +106,7 @@
</div> </div>
</div> </div>
<div <div
class="lg:w-auto w-full lg:text-right self-end {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}brightness-80{% endif %}"> class="lg:w-auto w-full lg:text-right self-end {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}opacity-70{% endif %}">
<div class="main-amount mb-2 lg:mb-0"> <div class="main-amount mb-2 lg:mb-0">
<c-amount.display <c-amount.display
:amount="transaction.amount" :amount="transaction.amount"
@@ -161,7 +161,8 @@
<button class="btn btn-neutral btn-sm transaction-action" data-bs-toggle="dropdown" data-bs-container="body" aria-expanded="false"> <button class="btn btn-neutral btn-sm transaction-action" data-bs-toggle="dropdown" data-bs-container="body" aria-expanded="false">
<i class="fa-solid fa-ellipsis fa-fw"></i> <i class="fa-solid fa-ellipsis fa-fw"></i>
</button> </button>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start menu w-max"> <ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start menu w-max relative">
<div class="absolute inset-[0rem_-3rem_-3rem_-3rem] pointer-events-auto -z-10"></div>
{% if transaction.account.is_untracked_by %} {% if transaction.account.is_untracked_by %}
<li> <li>
<a class="disabled flex items-center" aria-disabled="true"> <a class="disabled flex items-center" aria-disabled="true">
@@ -216,13 +217,13 @@
class="fa-solid fa-clone fa-fw mr-2"></i>{% translate 'Duplicate' %}</a></li> class="fa-solid fa-clone fa-fw mr-2"></i>{% translate 'Duplicate' %}</a></li>
</ul> </ul>
{% else %} {% else %}
<div class="tooltip" data-tip="{% translate "Restore" %}"> <div class="tooltip" data-tippy-content="{% translate "Restore" %}">
<a class="btn btn-secondary btn-sm transaction-action" <a class="btn btn-secondary btn-sm transaction-action"
role="button" role="button"
hx-get="{% url 'transaction_undelete' transaction_id=transaction.id %}"><i hx-get="{% url 'transaction_undelete' transaction_id=transaction.id %}"><i
class="fa-solid fa-trash-arrow-up"></i></a> class="fa-solid fa-trash-arrow-up"></i></a>
</div> </div>
<div class="tooltip" data-tip="{% translate "Delete" %}"> <div class="tooltip" data-tippy-content="{% translate "Delete" %}">
<a class="btn btn-secondary btn-sm transaction-action" <a class="btn btn-secondary btn-sm transaction-action"
role="button" role="button"
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}" hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
+61 -50
View File
@@ -11,66 +11,70 @@
{{ account.account.name }} {{ account.account.name }}
</h5> </h5>
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'projected income' %}</div> <div class="text-subtle">{% translate 'projected income' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
{% if account.income_projected != 0 %} {% if account.income_projected != 0 %}
<div class="text-end font-mono text-green-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.income_projected" :amount="account.income_projected"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
:suffix="account.currency.suffix" :suffix="account.currency.suffix"
:decimal_places="account.currency.decimal_places"></c-amount.display> :decimal_places="account.currency.decimal_places"
color="green"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end ">-</div>
{% endif %} {% endif %}
</div> </div>
{% if account.exchanged and account.exchanged.income_projected %} {% if account.exchanged and account.exchanged.income_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.income_projected" :amount="account.exchanged.income_projected"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'projected expenses' %}</div> <div class="text-subtle">{% translate 'projected expenses' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div> <div>
{% if account.expense_projected != 0 %} {% if account.expense_projected != 0 %}
<div class="text-end font-mono text-red-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.expense_projected" :amount="account.expense_projected"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
:suffix="account.currency.suffix" :suffix="account.currency.suffix"
:decimal_places="account.currency.decimal_places"></c-amount.display> :decimal_places="account.currency.decimal_places"
color="red"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end ">-</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% if account.exchanged and account.exchanged.expense_projected %} {% if account.exchanged and account.exchanged.expense_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.expense_projected" :amount="account.exchanged.expense_projected"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'projected total' %}</div> <div class="text-subtle">{% translate 'projected total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div <div
class="text-end font-mono"> class="text-end ">
<c-amount.display <c-amount.display
:amount="account.total_projected" :amount="account.total_projected"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
@@ -80,73 +84,78 @@
</div> </div>
</div> </div>
{% if account.exchanged.total_projected and account.exchanged.total_projected %} {% if account.exchanged.total_projected and account.exchanged.total_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.total_projected" :amount="account.exchanged.total_projected"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<hr class="my-3"> <hr class="my-3">
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'current income' %}</div> <div class="text-subtle">{% translate 'current income' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
{% if account.income_current != 0 %} {% if account.income_current != 0 %}
<div class="text-end font-mono text-green-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.income_current" :amount="account.income_current"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
:suffix="account.currency.suffix" :suffix="account.currency.suffix"
:decimal_places="account.currency.decimal_places"></c-amount.display> :decimal_places="account.currency.decimal_places"
color="green"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end ">-</div>
{% endif %} {% endif %}
</div> </div>
{% if account.exchanged and account.exchanged.income_current %} {% if account.exchanged and account.exchanged.income_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.income_current" :amount="account.exchanged.income_current"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'current expenses' %}</div> <div class="text-subtle">{% translate 'current expenses' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line"></div>
{% if account.expense_current != 0 %} {% if account.expense_current != 0 %}
<div class="text-end font-mono text-red-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.expense_current" :amount="account.expense_current"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
:suffix="account.currency.suffix" :suffix="account.currency.suffix"
:decimal_places="account.currency.decimal_places"></c-amount.display> :decimal_places="account.currency.decimal_places"
color="red"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end ">-</div>
{% endif %} {% endif %}
</div> </div>
{% if account.exchanged and account.exchanged.expense_current %} {% if account.exchanged and account.exchanged.expense_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.expense_current" :amount="account.exchanged.expense_current"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'current total' %}</div> <div class="text-subtle">{% translate 'current total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-linegrow"></div>
<div class="text-end font-mono"> <div class="text-end ">
<c-amount.display <c-amount.display
:amount="account.total_current" :amount="account.total_current"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
@@ -156,22 +165,23 @@
</div> </div>
</div> </div>
{% if account.exchanged and account.exchanged.total_current %} {% if account.exchanged and account.exchanged.total_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.total_current" :amount="account.exchanged.total_current"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div> <div>
<hr class="my-3"> <hr class="my-3">
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end ">
<div class="text-gray-400">{% translate 'final total' %}</div> <div class="text-subtle">{% translate 'final total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div class="text-end font-mono"> <div class="text-end ">
<c-amount.display <c-amount.display
:amount="account.total_final" :amount="account.total_final"
:prefix="account.currency.prefix" :prefix="account.currency.prefix"
@@ -181,12 +191,13 @@
</div> </div>
</div> </div>
{% if account.exchanged and account.exchanged.total_final %} {% if account.exchanged and account.exchanged.total_final %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="account.exchanged.total_final" :amount="account.exchanged.total_final"
:prefix="account.exchanged.currency.prefix" :prefix="account.exchanged.currency.prefix"
:suffix="account.exchanged.currency.suffix" :suffix="account.exchanged.currency.suffix"
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="account.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
</div> </div>
+63 -52
View File
@@ -6,65 +6,69 @@
{{ currency.currency.name }} {{ currency.currency.name }}
</h5> </h5>
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'projected income' %}</div> <div class="text-subtle">{% translate 'projected income' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
{% if currency.income_projected != 0 %} {% if currency.income_projected != 0 %}
<div class="text-end font-mono text-green-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.income_projected" :amount="currency.income_projected"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
:suffix="currency.currency.suffix" :suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"></c-amount.display> :decimal_places="currency.currency.decimal_places"
color="green"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end">-</div>
{% endif %} {% endif %}
</div> </div>
{% if currency.exchanged and currency.exchanged.income_projected %} {% if currency.exchanged and currency.exchanged.income_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.income_projected" :amount="currency.exchanged.income_projected"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'projected expenses' %}</div> <div class="text-subtle">{% translate 'projected expenses' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div> <div>
{% if currency.expense_projected != 0 %} {% if currency.expense_projected != 0 %}
<div class="text-end font-mono text-red-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.expense_projected" :amount="currency.expense_projected"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
:suffix="currency.currency.suffix" :suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"></c-amount.display> :decimal_places="currency.currency.decimal_places"
color="red"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end">-</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% if currency.exchanged and currency.exchanged.expense_projected %} {% if currency.exchanged and currency.exchanged.expense_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.expense_projected" :amount="currency.exchanged.expense_projected"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'projected total' %}</div> <div class="text-subtle">{% translate 'projected total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-linegrow"></div>
<div class="text-end font-mono"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.total_projected" :amount="currency.total_projected"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
@@ -74,73 +78,78 @@
</div> </div>
</div> </div>
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %} {% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.total_projected" :amount="currency.exchanged.total_projected"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<hr class="my-3"> <hr class="my-3 hr">
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'current income' %}</div> <div class="text-subtle">{% translate 'current income' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
{% if currency.income_current != 0 %} {% if currency.income_current != 0 %}
<div class="text-end font-mono text-green-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.income_current" :amount="currency.income_current"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
:suffix="currency.currency.suffix" :suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"></c-amount.display> :decimal_places="currency.currency.decimal_places"
color="green"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end">-</div>
{% endif %} {% endif %}
</div> </div>
{% if currency.exchanged and currency.exchanged.income_current %} {% if currency.exchanged and currency.exchanged.income_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.income_current" :amount="currency.exchanged.income_current"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'current expenses' %}</div> <div class="text-subtle">{% translate 'current expenses' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
{% if currency.expense_current != 0 %} {% if currency.expense_current != 0 %}
<div class="text-end font-mono text-red-400"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.expense_current" :amount="currency.expense_current"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
:suffix="currency.currency.suffix" :suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"></c-amount.display> :decimal_places="currency.currency.decimal_places"
color="red"></c-amount.display>
</div> </div>
{% else %} {% else %}
<div class="text-end font-mono">-</div> <div class="text-end">-</div>
{% endif %} {% endif %}
</div> </div>
{% if currency.exchanged and currency.exchanged.expense_current %} {% if currency.exchanged and currency.exchanged.expense_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.expense_current" :amount="currency.exchanged.expense_current"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'current total' %}</div> <div class="text-subtle">{% translate 'current total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div class="text-end font-mono"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.total_current" :amount="currency.total_current"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
@@ -150,22 +159,23 @@
</div> </div>
</div> </div>
{% if currency.exchanged and currency.exchanged.total_current %} {% if currency.exchanged and currency.exchanged.total_current %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.total_current" :amount="currency.exchanged.total_current"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
<div> <div>
<hr class="my-3"> <hr class="my-3 hr">
<div class="flex justify-between items-baseline mt-2"> <div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono"> <div class="text-end">
<div class="text-gray-400">{% translate 'final total' %}</div> <div class="text-subtle">{% translate 'final total' %}</div>
</div> </div>
<div class="dotted-line flex-grow"></div> <div class="dotted-line grow"></div>
<div class="text-end font-mono"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.total_final" :amount="currency.total_final"
:prefix="currency.currency.prefix" :prefix="currency.currency.prefix"
@@ -175,12 +185,13 @@
</div> </div>
</div> </div>
{% if currency.exchanged and currency.exchanged.total_final %} {% if currency.exchanged and currency.exchanged.total_final %}
<div class="text-end font-mono text-gray-500"> <div class="text-end">
<c-amount.display <c-amount.display
:amount="currency.exchanged.total_final" :amount="currency.exchanged.total_final"
:prefix="currency.exchanged.currency.prefix" :prefix="currency.exchanged.currency.prefix"
:suffix="currency.exchanged.currency.suffix" :suffix="currency.exchanged.currency.suffix"
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display> :decimal_places="currency.exchanged.currency.decimal_places"
color="gray"></c-amount.display>
</div> </div>
{% endif %} {% endif %}
</div> </div>
+1 -3
View File
@@ -1,8 +1,6 @@
{% spaceless %} {% spaceless %}
{% load i18n %} {% load i18n %}
<div class="tooltip" data-tip="{{ content }}"> <span class="text-xs text-base-content/50 mx-1" data-tippy-content="{{ content }}">
<span class="text-xs text-base-content/50 mx-3">
<i class="{% if not icon %}fa-solid fa-circle-question{% else %}{{ icon }}{% endif %} fa-fw"></i> <i class="{% if not icon %}fa-solid fa-circle-question{% else %}{{ icon }}{% endif %} fa-fw"></i>
</span> </span>
</div>
{% endspaceless %} {% endspaceless %}
+1 -1
View File
@@ -1,4 +1,4 @@
<div class="card card-border border-2 border-base-300 relative h-full shadow bg-base-100"> <div class="card card-border relative h-full shadow bg-base-100">
<div class="absolute h-8 w-8 right-2 top-2 bg-{{ color }}-300 text-{{ color }}-800 text-center flex items-center justify-center rounded-lg"> <div class="absolute h-8 w-8 right-2 top-2 bg-{{ color }}-300 text-{{ color }}-800 text-center flex items-center justify-center rounded-lg">
{% if icon %}<i class="{{ icon }}"></i>{% else %}<span class="font-bold">{{ title.0 }}</span>{% endif %} {% if icon %}<i class="{{ icon }}"></i>{% else %}<span class="font-bold">{{ title.0 }}</span>{% endif %}
</div> </div>
@@ -8,7 +8,7 @@
{% if percentage.percentages.income_projected > 0 %}rounded-s-full{% endif %} {% if percentage.percentages.income_projected > 0 %}rounded-s-full{% endif %}
{% if percentage.percentages.income_projected > 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}" {% if percentage.percentages.income_projected > 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}"
style="width: {{ percentage.percentages.income_projected|floatformat:'2u' }}%" style="width: {{ percentage.percentages.income_projected|floatformat:'2u' }}%"
data-tip="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)" data-tippy-content="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)"
role="progressbar" role="progressbar"
aria-label="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)" aria-label="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)"
aria-valuenow="{{ percentage.percentages.income_projected|floatformat:0 }}" aria-valuenow="{{ percentage.percentages.income_projected|floatformat:0 }}"
@@ -21,7 +21,7 @@
{% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current > 0 %}rounded-s-full{% endif %} {% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current > 0 %}rounded-s-full{% endif %}
{% if percentage.percentages.income_current > 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}" {% if percentage.percentages.income_current > 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}"
style="width: {{ percentage.percentages.income_current|floatformat:'2u' }}%" style="width: {{ percentage.percentages.income_current|floatformat:'2u' }}%"
data-tip="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)" data-tippy-content="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)"
role="progressbar" role="progressbar"
aria-label="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)" aria-label="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)"
aria-valuenow="{{ percentage.percentages.income_current|floatformat:0 }}" aria-valuenow="{{ percentage.percentages.income_current|floatformat:0 }}"
@@ -34,7 +34,7 @@
{% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected > 0 %}rounded-s-full{% endif %} {% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected > 0 %}rounded-s-full{% endif %}
{% if percentage.percentages.expense_projected > 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}" {% if percentage.percentages.expense_projected > 0 and percentage.percentages.expense_current <= 0 %}rounded-e-full{% endif %}"
style="width: {{ percentage.percentages.expense_projected|floatformat:'2u' }}%" style="width: {{ percentage.percentages.expense_projected|floatformat:'2u' }}%"
data-tip="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)" data-tippy-content="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)"
role="progressbar" role="progressbar"
aria-label="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)" aria-label="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)"
aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}"
@@ -47,7 +47,7 @@
{% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current > 0 %}rounded-s-full{% endif %} {% if percentage.percentages.income_projected <= 0 and percentage.percentages.income_current <= 0 and percentage.percentages.expense_projected <= 0 and percentage.percentages.expense_current > 0 %}rounded-s-full{% endif %}
{% if percentage.percentages.expense_current > 0 %}rounded-e-full{% endif %}" {% if percentage.percentages.expense_current > 0 %}rounded-e-full{% endif %}"
style="width: {{ percentage.percentages.expense_current|floatformat:'2u' }}%" style="width: {{ percentage.percentages.expense_current|floatformat:'2u' }}%"
data-tip="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)" data-tippy-content="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)"
role="progressbar" role="progressbar"
aria-label="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)" aria-label="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)"
aria-valuenow="{{ percentage.percentages.expense_current|floatformat:0 }}" aria-valuenow="{{ percentage.percentages.expense_current|floatformat:0 }}"
+111 -98
View File
@@ -6,114 +6,127 @@
{% block content %} {% block content %}
<div class="container-fluid"> <div class="container-fluid">
<div class="flex flex-wrap my-3 h-full"> <div class="row">
<div class="w-full lg:w-2/12 md:w-3/12 mb-3 md:mb-0"> <div class="col-12 md:col-3">
<div class="sticky top-3"> <div class="flex flex-col gap-3">
<div class=""> <div class="card bg-base-100 card-borderS">
<div class="mb-2 w-full lg:inline-flex grid gap-2 flex-wrap lg:justify-center" role="group" <div class="card-body">
_="on change <div class="">
set type to event.target.value <div class="mb-2 w-full lg:inline-flex grid gap-2 flex-wrap lg:justify-center" role="group"
add .hidden to <#picker-form > div:not(.hidden)/> _="on change
set type to event.target.value
add .hidden to <#picker-form > div:not(.hidden)/>
if type == 'month' if type == 'month'
remove .hidden from #month-form remove .hidden from #month-form
end end
if type == 'year' if type == 'year'
remove .hidden from #year-form remove .hidden from #year-form
end end
if type == 'month-range' if type == 'month-range'
remove .hidden from #month-range-form remove .hidden from #month-range-form
end end
if type == 'year-range' if type == 'year-range'
remove .hidden from #year-range-form remove .hidden from #year-range-form
end end
if type == 'date-range' if type == 'date-range'
remove .hidden from #date-range-form remove .hidden from #date-range-form
end end
then trigger updated" then trigger updated"
id="picker-type"> id="picker-type">
<input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="month" id="monthradio" autocomplete="off" aria-label="{% translate 'Month' %}" checked> <input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="month" id="monthradio" autocomplete="off" aria-label="{% translate 'Month' %}" checked>
<input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="year" id="yearradio" autocomplete="off" aria-label="{% translate 'Year' %}"> <input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="year" id="yearradio" autocomplete="off" aria-label="{% translate 'Year' %}">
<input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="month-range" id="monthrangeradio" autocomplete="off" aria-label="{% translate 'Month Range' %}"> <input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="month-range" id="monthrangeradio" autocomplete="off" aria-label="{% translate 'Month Range' %}">
<input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="year-range" id="yearrangeradio" autocomplete="off" aria-label="{% translate 'Year Range' %}"> <input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="year-range" id="yearrangeradio" autocomplete="off" aria-label="{% translate 'Year Range' %}">
<input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="date-range" id="daterangeradio" autocomplete="off" aria-label="{% translate 'Date Range' %}"> <input type="radio" class="join-item btn btn-sm btn-outline btn-primary flex-grow" name="type" value="date-range" id="daterangeradio" autocomplete="off" aria-label="{% translate 'Date Range' %}">
</div>
<form id="picker-form"
_="install init_datepicker
on change trigger updated">
<div id="month-form" class="">
{% crispy month_form %}
</div>
<div id="year-form" class="hidden">
{% crispy year_form %}
</div>
<div id="month-range-form" class="hidden">
{% crispy month_range_form %}
</div>
<div id="year-range-form" class="hidden">
{% crispy year_range_form %}
</div>
<div id="date-range-form" class="hidden">
{% crispy date_range_form %}
</div>
</form>
</div>
<div class="flex flex-col gap-1 insights-list" role="tablist"
hx-indicator="#tab-content"
hx-target="#tab-content"
hx-sync="#tab-content:replace"
hx-include="#picker-form, #picker-type"
_="on click
remove .btn-active from <.insights-list button/>
add .btn-active to event.target
set event.target's @aria-selected to 'true'">
<button class="btn btn-ghost justify-start"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'insights_sankey_by_account' %}">
{% trans 'Account Flow' %}
</button>
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'insights_sankey_by_currency' %}"
>{% trans 'Currency Flow' %}
</button>
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'category_explorer_index' %}">
{% trans 'Category Explorer' %}
</button>
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'category_overview' %}"
>{% trans 'Categories Overview' %}
</button>
</div>
</div> </div>
<form id="picker-form"
_="install init_datepicker
on change trigger updated">
<div id="month-form" class="">
{% crispy month_form %}
</div>
<div id="year-form" class="hidden">
{% crispy year_form %}
</div>
<div id="month-range-form" class="hidden">
{% crispy month_range_form %}
</div>
<div id="year-range-form" class="hidden">
{% crispy year_range_form %}
</div>
<div id="date-range-form" class="hidden">
{% crispy date_range_form %}
</div>
</form>
</div> </div>
<div class="menu menu-vertical flex-col" id="v-pills-tab" role="tablist" <div class="card bg-base-100 card-border">
aria-orientation="vertical"> <div class="card-body">
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content" <div class="flex flex-col gap-1 insights-list" role="tablist"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false" hx-indicator="#tab-content"
hx-get="{% url 'insights_sankey_by_account' %}" hx-include="#picker-form, #picker-type" hx-target="#tab-content"
hx-indicator="#tab-content" hx-sync="#tab-content:replace"
hx-target="#tab-content">{% trans 'Account Flow' %} _="on click
</button> remove .btn-active from <.insights-list button/>
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content" add .btn-active to event.target
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false" set event.target's @aria-selected to 'true'">
hx-get="{% url 'insights_sankey_by_currency' %}" <button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
hx-include="#picker-form, #picker-type" type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-indicator="#tab-content" hx-get="{% url 'insights_late_transactions' %}">
hx-target="#tab-content">{% trans 'Currency Flow' %} {% trans 'Late Transactions' %}
</button> </button>
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content" <button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false" type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'category_explorer_index' %}" hx-get="{% url 'insights_latest_transactions' %}">
hx-include="#picker-form, #picker-type" {% trans 'Latest Transactions' %}
hx-indicator="#tab-content" </button>
hx-target="#tab-content">{% trans 'Category Explorer' %} <button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
</button> type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content" hx-get="{% url 'insights_emergency_fund' %}">
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false" {% trans 'Emergency Fund' %}
hx-get="{% url 'category_overview' %}" </button>
hx-include="#picker-form, #picker-type" </div>
hx-indicator="#tab-content" </div>
hx-target="#tab-content">{% trans 'Categories Overview' %}
</button>
<hr class="hr">
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'insights_late_transactions' %}"
hx-indicator="#tab-content"
hx-target="#tab-content">{% trans 'Late Transactions' %}
</button>
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'insights_latest_transactions' %}"
hx-indicator="#tab-content"
hx-target="#tab-content">{% trans 'Latest Transactions' %}
</button>
<button class="btn btn-ghost justify-start" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'insights_emergency_fund' %}"
hx-indicator="#tab-content"
hx-target="#tab-content">{% trans 'Emergency Fund' %}
</button>
</div> </div>
</div> </div>
</div> </div>
<div class="w-full md:w-9/12 lg:w-10/12"> <div class="col-12 md:col-9">
<div id="tab-content" class="show-loading"></div> <div id="tab-content" class="show-loading"></div>
</div> </div>
</div> </div>
@@ -6,7 +6,7 @@
<c-ui.info-card color="yellow" icon="fa-solid fa-calendar-day" title="{% trans 'Daily Spending Allowance' %}" help_text={% trans "This is the final total divided by the remaining days in the month" %}> <c-ui.info-card color="yellow" icon="fa-solid fa-calendar-day" title="{% trans 'Daily Spending Allowance' %}" help_text={% trans "This is the final total divided by the remaining days in the month" %}>
<div class="flex justify-between mt-3"> <div class="flex justify-between mt-3">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'today' %}</div> <div class="text-subtle">{% translate 'today' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in daily_spending_allowance.values %} {% for currency in daily_spending_allowance.values %}
@@ -39,7 +39,7 @@
<c-ui.info-card color="green" icon="fa-solid fa-arrow-right-to-bracket" title="{% trans 'Income' %}"> <c-ui.info-card color="green" icon="fa-solid fa-arrow-right-to-bracket" title="{% trans 'Income' %}">
<div class="flex justify-between mt-3"> <div class="flex justify-between mt-3">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'current' %}</div> <div class="text-subtle">{% translate 'current' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in income_current.values %} {% for currency in income_current.values %}
@@ -68,7 +68,7 @@
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'projected' %}</div> <div class="text-subtle">{% translate 'projected' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in income_projected.values %} {% for currency in income_projected.values %}
@@ -102,7 +102,7 @@
<c-ui.info-card color="red" icon="fa-solid fa-arrow-right-from-bracket" title="{% trans 'Expenses' %}"> <c-ui.info-card color="red" icon="fa-solid fa-arrow-right-from-bracket" title="{% trans 'Expenses' %}">
<div class="flex justify-between mt-3"> <div class="flex justify-between mt-3">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'current' %}</div> <div class="text-subtle">{% translate 'current' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in expense_current.values %} {% for currency in expense_current.values %}
@@ -131,7 +131,7 @@
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'projected' %}</div> <div class="text-subtle">{% translate 'projected' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in expense_projected.values %} {% for currency in expense_projected.values %}
@@ -165,7 +165,7 @@
<c-ui.info-card color="blue" icon="fa-solid fa-scale-balanced" title="{% trans 'Total' %}"> <c-ui.info-card color="blue" icon="fa-solid fa-scale-balanced" title="{% trans 'Total' %}">
<div class="flex justify-between mt-3"> <div class="flex justify-between mt-3">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'current' %}</div> <div class="text-subtle">{% translate 'current' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in total_current.values %} {% for currency in total_current.values %}
@@ -194,7 +194,7 @@
</div> </div>
<div class="flex justify-between mt-3"> <div class="flex justify-between mt-3">
<div class="text-right font-mono"> <div class="text-right font-mono">
<div class="text-base-content/90">{% translate 'projected' %}</div> <div class="text-subtle">{% translate 'projected' %}</div>
</div> </div>
<div class="text-right font-mono"> <div class="text-right font-mono">
{% for currency in total_projected.values %} {% for currency in total_projected.values %}
@@ -254,7 +254,7 @@
<div> <div>
<c-ui.info-card color="yellow" icon="fa-solid fa-percent" title="{% trans 'Distribution' %}"> <c-ui.info-card color="yellow" icon="fa-solid fa-percent" title="{% trans 'Distribution' %}">
{% for p in percentages.values %} {% for p in percentages.values %}
<p class="text-base-content/90 {% if not forloop.first %}mt-3{% endif %}">{{ p.currency.name }}</p> <p class="text-subtle {% if not forloop.first %}mt-3{% endif %}">{{ p.currency.name }}</p>
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution> <c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
{% endfor %} {% endfor %}
</c-ui.info-card> </c-ui.info-card>
-6
View File
@@ -34,12 +34,6 @@
value="projected" value="projected"
{% if type == "projected" %}checked{% endif %} /> {% if type == "projected" %}checked{% endif %} />
</div> </div>
{% comment %} <div class="gap-3" role="group" id="view-type" _="on change trigger updated">
<input type="radio" class="btn btn-outline btn-primary rounded-full" name="view_type" aria-label="{% trans "Current" %}" autocomplete="off" value="current" {% if type == "current" %}checked{% endif %} />
<i class="fa-solid fa-circle-plus fa-fw"></i>{% trans "Current" %}
</input />
<input type="radio" class="btn btn-outline btn-primary rounded-full" name="view_type" aria-label="{% trans "Projected" %}" autocomplete="off" value="projected" {% if type == "projected" %}checked{% endif %} />
</div> {% endcomment %}
</div> </div>
<div class="container px-md-3 py-3" <div class="container px-md-3 py-3"
_="init call initializeAccountChart() then initializeCurrencyChart() then initializeMonthlyDifferenceChart() end"> _="init call initializeAccountChart() then initializeCurrencyChart() then initializeMonthlyDifferenceChart() end">
@@ -17,9 +17,9 @@
{% block filter_pills %} {% block filter_pills %}
<input type="hidden" name="account" value=""> <input type="hidden" name="account" value="">
<div class="join join-vertical flex-col" id="filter-pills" role="tablist" <div class="flex flex-col w-full gap-1" id="filter-pills" role="tablist"
hx-indicator="#data-content"> hx-indicator="#data-content">
<button class="btn btn-outline btn-primary btn-active justify-start join-item" <button class="btn btn-ghost btn-active justify-start w-full"
role="tab" role="tab"
hx-get="{% url 'yearly_overview_account_data' year=year %}" hx-get="{% url 'yearly_overview_account_data' year=year %}"
hx-target="#data-content" hx-target="#data-content"
@@ -33,7 +33,7 @@
{% translate 'All' %} {% translate 'All' %}
</button> </button>
{% for account in accounts %} {% for account in accounts %}
<button class="btn btn-outline btn-primary justify-start join-item" <button class="btn btn-ghost justify-start w-full"
role="tab" role="tab"
hx-get="{% url 'yearly_overview_account_data' year=year %}" hx-get="{% url 'yearly_overview_account_data' year=year %}"
hx-target="#data-content" hx-target="#data-content"
@@ -44,7 +44,7 @@
_="on click _="on click
remove .btn-active from <button/> in #filter-pills remove .btn-active from <button/> in #filter-pills
add .btn-active to me"> add .btn-active to me">
{% if account.group.name %}<span class="badge badge-secondary me-2">{{ account.group.name }}</span>{% endif %} {{ account.name }} {% if account.group.name %}<span class="badge badge-primary me-2">{{ account.group.name }}</span>{% endif %} {{ account.name }}
</button> </button>
{% endfor %} {% endfor %}
</div> </div>
@@ -19,9 +19,9 @@
{% block filter_pills %} {% block filter_pills %}
<input type="hidden" name="currency" value=""> <input type="hidden" name="currency" value="">
<div class="join join-vertical flex-col" id="filter-pills" role="tablist" <div class="flex flex-col w-full gap-1" id="filter-pills" role="tablist"
hx-indicator="#data-content"> hx-indicator="#data-content">
<button class="btn btn-outline btn-primary btn-active justify-start join-item" <button class="btn btn-ghost btn-active justify-start w-full"
role="tab" role="tab"
hx-get="{% url 'yearly_overview_currency_data' year=year %}" hx-get="{% url 'yearly_overview_currency_data' year=year %}"
hx-target="#data-content" hx-target="#data-content"
@@ -35,7 +35,7 @@
{% translate 'All' %} {% translate 'All' %}
</button> </button>
{% for currency in currencies %} {% for currency in currencies %}
<button class="btn btn-outline btn-primary justify-start join-item" <button class="btn btn-ghost justify-start w-full"
role="tab" role="tab"
hx-get="{% url 'yearly_overview_currency_data' year=year %}" hx-get="{% url 'yearly_overview_currency_data' year=year %}"
hx-target="#data-content" hx-target="#data-content"
@@ -11,18 +11,17 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="h-full text-center mb-4 pt-2"> <div class="h-full text-center mb-4 pt-2 w-full">
<div class="btn-group gap-3" role="group"> <div role="tablist" class="tabs tabs-box mx-auto w-fit">
<a href="{% url 'yearly_overview_currency' year=year %}" class="btn {% if type != 'currency' %}btn-outline btn-primary{% else %}btn-primary{% endif %} rounded-full" hx-boost> <a href="{% url 'yearly_overview_currency' year=year %}" class="tab {% if type == 'currency' %}tab-active{% endif %}" hx-boost>
<i class="fa-solid fa-solid fa-coins fa-fw me-2"></i>{% trans 'Currency' %} <i class="fa-solid fa-solid fa-coins fa-fw me-2"></i>{% trans 'Currency' %}
</a> </a>
<a href="{% url 'yearly_overview_account' year=year %}" class="tab {% if type == 'account' %}tab-active{% endif %}" hx-boost>
<a href="{% url 'yearly_overview_account' year=year %}" class="btn {% if type != 'account' %}btn-outline btn-primary{% else %}btn-primary{% endif %} rounded-full" hx-boost>
<i class="fa-solid fa-wallet fa-fw me-2"></i>{% trans 'Account' %} <i class="fa-solid fa-wallet fa-fw me-2"></i>{% trans 'Account' %}
</a> </a>
</div> </div>
</div> </div>
<div class="container px-md-3 py-3 gap-x-5 overflow-x-hidden" id="yearly-content"> <div class="container" id="yearly-content">
<div class="flex flex-wrap mb-4 gap-x-xl-4 gap-y-3"> <div class="flex flex-wrap mb-4 gap-x-xl-4 gap-y-3">
{# Date picker#} {# Date picker#}
<div class="w-full xl:w-auto flex-row items-center flex"> <div class="w-full xl:w-auto flex-row items-center flex">
@@ -33,7 +32,7 @@
href="{% block previous_year_url %}{% endblock %}"> href="{% block previous_year_url %}{% endblock %}">
<i class="fa-solid fa-chevron-left"></i></a> <i class="fa-solid fa-chevron-left"></i></a>
</div> </div>
<div class="text-2xl font-bold btn btn-ghost flex-1 text-center whitespace-normal flex-wrap h-auto min-w-0"> <div class="text-2xl font-bold flex-1 text-center whitespace-normal flex-wrap h-auto min-w-0">
{{ year }} {{ year }}
</div> </div>
<div class="text-base mx-2 h-full items-center flex btn btn-ghost"> <div class="text-base mx-2 h-full items-center flex btn btn-ghost">
@@ -46,48 +45,56 @@
</div> </div>
</div> </div>
</div> </div>
<div class="flex flex-wrap"> <div class="row gap-y-3">
<div class="w-full lg:w-2/12"> <div class="col-12 xl:col-3">
<input type="hidden" name="month" value=""> <div class="card bg-base-100 card-border">
<div class="flex-col join join-vertical" id="month-pills" role="tablist" <div class="card-body">
hx-indicator="#data-content"> <input type="hidden" name="month" value="">
<button class="btn btn-outline btn-primary btn-active justify-start join-item" <div class="flex flex-col gap-1 w-full" id="month-pills" role="tablist"
role="tab" hx-indicator="#data-content">
hx-get="{% block data_url %}{% endblock %}" <button class="btn btn-ghost btn-active justify-start w-full"
hx-target="#data-content" role="tab"
hx-trigger="click" hx-get="{% block data_url %}{% endblock %}"
hx-include="{% block hx_include %}{% endblock %}" hx-target="#data-content"
hx-swap="innerHTML" hx-trigger="click"
onclick="document.querySelector('[name=month]').value = ''" hx-include="{% block hx_include %}{% endblock %}"
_="on click hx-swap="innerHTML"
remove .btn-active from <button/> in #month-pills onclick="document.querySelector('[name=month]').value = ''"
add .btn-active to me"> _="on click
{% translate 'Year' %} remove .btn-active from <button/> in #month-pills
</button> add .btn-active to me">
{% for month in months %} {% translate 'Year' %}
<button class="btn btn-outline btn-primary justify-start join-item" </button>
role="tab" {% for month in months %}
hx-get="{% block month_data_url %}{% endblock %}" <button class="btn btn-ghost justify-start w-full"
hx-target="#data-content" role="tab"
hx-trigger="click" hx-get="{% block month_data_url %}{% endblock %}"
hx-include="{% block month_hx_include %}{% endblock %}" hx-target="#data-content"
hx-swap="innerHTML" hx-trigger="click"
onclick="document.querySelector('[name=month]').value = '{{ month }}'" hx-include="{% block month_hx_include %}{% endblock %}"
_="on click hx-swap="innerHTML"
remove .btn-active from <button/> in #month-pills onclick="document.querySelector('[name=month]').value = '{{ month }}'"
add .btn-active to me"> _="on click
{{ month|month_name }} remove .btn-active from <button/> in #month-pills
</button> add .btn-active to me">
{% endfor %} {{ month|month_name }}
</button>
{% endfor %}
</div>
</div>
</div> </div>
</div> </div>
<hr class="my-4 block lg:hidden"> <div class="col-12 xl:col-3">
<div class="w-full lg:w-3/12"> <div class="card bg-base-100 card-border">
{% block filter_pills %}{% endblock %} <div class="card-body">
{% block filter_pills %}{% endblock %}
</div>
</div>
</div> </div>
<div class="w-full lg:w-7/12"> <div class="col-12 xl:col-6">
<hr class="xl:hidden my-3 hr">
<div id="data-content" <div id="data-content"
class="show-loading" class="show-loading"
hx-get="{% block content_data_url %}{% endblock %}" hx-get="{% block content_data_url %}{% endblock %}"
+23 -10
View File
@@ -61,6 +61,7 @@
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
transform: rotate(360deg); transform: rotate(360deg);
} }
@@ -70,6 +71,7 @@
0% { 0% {
opacity: 0; opacity: 0;
} }
100% { 100% {
opacity: 1; opacity: 1;
} }
@@ -79,14 +81,15 @@
position: relative; position: relative;
top: 0; top: 0;
min-height: 100px; min-height: 100px;
overflow: hidden;
&::before { &::before {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; top: -10px;
left: 0; left: -10px;
right: 0; right: -10px;
bottom: 0; bottom: -10px;
backdrop-filter: blur(4px); backdrop-filter: blur(4px);
z-index: 100; z-index: 100;
animation: fade-in 0.1s ease-in forwards; animation: fade-in 0.1s ease-in forwards;
@@ -101,13 +104,13 @@
left: 50%; left: 50%;
width: 40px; width: 40px;
height: 40px; height: 40px;
border: 4px solid #f3f3f3; border: 4px solid var(--color-primary);
//border-top: 4px solid $primary; border-top: 4px solid var(--color-base-300);
border-radius: 50%; border-radius: 50%;
animation: spin 1s linear infinite, fade-in 0.1s ease-in forwards; animation: spin 1s linear infinite, fade-in 0.1s ease-in forwards;
animation-delay: 200ms; animation-delay: 200ms;
opacity: 0; opacity: 0;
z-index: 101; z-index: 9999;
} }
} }
@@ -133,6 +136,7 @@
transform-origin: top; transform-origin: top;
opacity: 1; opacity: 1;
} }
100% { 100% {
transform: rotateX(-100deg); transform: rotateX(-100deg);
transform-origin: top; transform-origin: top;
@@ -157,6 +161,7 @@
transform: scale(0); transform: scale(0);
opacity: 1; opacity: 1;
} }
100% { 100% {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
@@ -184,6 +189,7 @@
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
} }
100% { 100% {
transform: scale(0); transform: scale(0);
opacity: 1; opacity: 1;
@@ -195,9 +201,12 @@
} }
@keyframes flash { @keyframes flash {
0%, 100% {
0%,
100% {
opacity: 1; opacity: 1;
} }
50% { 50% {
opacity: 0.3; opacity: 0.3;
} }
@@ -233,6 +242,7 @@
transform: translateY(1000px); transform: translateY(1000px);
opacity: 0; opacity: 0;
} }
100% { 100% {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
@@ -240,10 +250,13 @@
} }
@keyframes disable-pointer-events { @keyframes disable-pointer-events {
0%, 99% {
0%,
99% {
pointer-events: none; pointer-events: none;
} }
100% { 100% {
pointer-events: auto; pointer-events: auto;
} }
} }
+1 -12
View File
@@ -1,14 +1,3 @@
// Bootstrap Utilities and Custom Bootstrap Components
// This file imports standalone implementations of Bootstrap components
// and contains Bootstrap-related utilities
// Standalone component implementations
@use "offcanvas"; @use "offcanvas";
@use "dropdown"; @use "dropdown";
@use "transitions"; @use "transitions";
// Bootstrap-specific utility classes
.dropdown-toggle.dropdown-toggle-no-icon::after {
display: none;
}
-11
View File
@@ -18,14 +18,6 @@ select {
display: none; display: none;
} }
// .ts-dropdown-content {
// max-height: 50vh;
// }
//.font-base {
// font-family: bootstrap.$font-family-base;
//}
::selection { ::selection {
color: variables.$gray-800; color: variables.$gray-800;
background-color: variables.$primary; background-color: variables.$primary;
@@ -51,9 +43,6 @@ select {
padding: 0 8px !important; padding: 0 8px !important;
} }
//.transaction:has(input[type="checkbox"]:checked) > div > .transaction-item {
// background-color: bootstrap.$primary-bg-subtle-dark;
//}
.offline { .offline {
text-align: center; text-align: center;
+49 -8
View File
@@ -17,8 +17,8 @@
--color-base-200: oklch(98% 0 0); --color-base-200: oklch(98% 0 0);
--color-base-300: oklch(96% 0 0); --color-base-300: oklch(96% 0 0);
--color-base-content: oklch(21% 0.006 285.885); --color-base-content: oklch(21% 0.006 285.885);
--color-primary: oklch(87% 0.169 91.605); --color-primary: #b07526;
--color-primary-content: oklch(41% 0.112 45.904); --color-primary-content: #fcf2e7;
--color-secondary: oklch(44% 0.043 257.281); --color-secondary: oklch(44% 0.043 257.281);
--color-secondary-content: oklch(98% 0.003 247.858); --color-secondary-content: oklch(98% 0.003 247.858);
--color-accent: oklch(70% 0.01 56.259); --color-accent: oklch(70% 0.01 56.259);
@@ -27,12 +27,12 @@
--color-neutral-content: oklch(92% 0.004 286.32); --color-neutral-content: oklch(92% 0.004 286.32);
--color-info: oklch(74% 0.16 232.661); --color-info: oklch(74% 0.16 232.661);
--color-info-content: oklch(29% 0.066 243.157); --color-info-content: oklch(29% 0.066 243.157);
--color-success: oklch(76% 0.177 163.223); --color-success: #4b8f45;
--color-success-content: oklch(37% 0.077 168.94); --color-success-content: #ebf6ea;
--color-warning: oklch(82% 0.189 84.429); --color-warning: #b07526;
--color-warning-content: oklch(41% 0.112 45.904); --color-warning-content: #fcf2e7;
--color-error: oklch(71% 0.194 13.428); --color-error: #b44041;
--color-error-content: oklch(27% 0.105 12.094); --color-error-content: #ffeae8;
--radius-selector: 0.5rem; --radius-selector: 0.5rem;
--radius-field: 0.5rem; --radius-field: 0.5rem;
--radius-box: 0.5rem; --radius-box: 0.5rem;
@@ -113,10 +113,51 @@
.hr { .hr {
@apply text-base-content/60; @apply text-base-content/60;
} }
.card.card-border-base-100 {
border: var(--border) solid var(--color-base-100);
}
.card.card-border-base-200 {
border: var(--border) solid var(--color-base-200);
}
.card.card-border {
border: var(--border) solid var(--color-base-200);
}
.card.card-border-base-300 {
border: var(--border) solid var(--color-base-300);
}
.text-income {
@apply text-success;
}
.text-expense {
@apply text-error;
}
.text-exchange-rate {
@apply text-base-content/60;
}
.text-subtle {
@apply text-base-content/80;
}
} }
@layer components { @layer components {
.fab {
@layer daisyui.component {
> :nth-child(n+7) {
transition-delay: 150ms;
}
}
}
/* === Sidebar styles === */ /* === Sidebar styles === */
.sidebar-active { .sidebar-active {
@apply text-primary-content bg-primary rounded-box; @apply text-primary-content bg-primary rounded-box;