Files
Personal-Finance-Management/app/templates/transactions/index.html
T
2026-05-31 11:17:53 -04:00

131 lines
7.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Transactions{% endblock %}
{% block page_title %}Transactions{% endblock %}
{% block topbar_actions %}
<a href="{{ url_for('transactions.new', type='income') }}" class="btn btn-sm" style="background:#d1fae5;color:#065f46;font-size:12px;"><i class="bi bi-plus-lg me-1"></i>Income</a>
<a href="{{ url_for('transactions.new', type='expense') }}" class="btn btn-sm ms-1" style="background:#fee2e2;color:#991b1b;font-size:12px;"><i class="bi bi-plus-lg me-1"></i>Expense</a>
<a href="{{ url_for('transactions.transfer') }}" class="btn btn-sm btn-outline-secondary ms-1" style="font-size:12px;"><i class="bi bi-arrow-left-right me-1"></i>Transfer</a>
{% endblock %}
{% block content %}
<!-- Tabs -->
<div class="d-flex gap-1 mb-3">
<a href="{{ url_for('transactions.index', tab='expense', q=search, account_id=account_id, category_id=category_id, date_from=date_from, date_to=date_to) }}"
class="btn btn-sm {% if tab=='expense' %}btn-danger{% else %}btn-outline-secondary{% endif %}" style="font-size:13px;">
<i class="bi bi-arrow-up-circle me-1"></i>Expenses
<span class="badge ms-1" style="font-size:10px;background:{% if tab=='expense' %}rgba(255,255,255,.25){% else %}#fee2e2;color:#991b1b{% endif %};">{{ expense_count }}</span>
</a>
<a href="{{ url_for('transactions.index', tab='income', q=search, account_id=account_id, category_id=category_id, date_from=date_from, date_to=date_to) }}"
class="btn btn-sm {% if tab=='income' %}btn-success{% else %}btn-outline-secondary{% endif %}" style="font-size:13px;">
<i class="bi bi-arrow-down-circle me-1"></i>Income
<span class="badge ms-1" style="font-size:10px;background:{% if tab=='income' %}rgba(255,255,255,.25){% else %}#d1fae5;color:#065f46{% endif %};">{{ income_count }}</span>
</a>
</div>
<!-- Filters -->
<div class="pcard pcard-sm mb-3">
<form method="GET" action="{{ url_for('transactions.index') }}" class="row g-2 align-items-end">
<input type="hidden" name="tab" value="{{ tab }}">
<div class="col-12 col-md-3">
<input type="text" name="q" class="form-control form-control-sm" placeholder="Search description…" value="{{ search }}">
</div>
<div class="col-6 col-md-2">
<select name="category_id" class="form-select form-select-sm">
<option value="">All categories</option>
{% for cat in categories %}
<option value="{{ cat.id }}" {% if category_id == cat.id|string %}selected{% endif %}>{{ cat.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-md-2">
<select name="account_id" class="form-select form-select-sm">
<option value="">All accounts</option>
{% for acct in accounts %}
<option value="{{ acct.id }}" {% if account_id == acct.id|string %}selected{% endif %}>{{ acct.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-md-2">
<input type="date" name="date_from" class="form-control form-control-sm" value="{{ date_from }}" placeholder="From">
</div>
<div class="col-6 col-md-2">
<input type="date" name="date_to" class="form-control form-control-sm" value="{{ date_to }}" placeholder="To">
</div>
<div class="col-12 col-md-1 d-flex gap-1">
<button type="submit" class="btn btn-sm btn-primary flex-grow-1"><i class="bi bi-search"></i></button>
<a href="{{ url_for('transactions.index', tab=tab) }}" class="btn btn-sm btn-outline-secondary"><i class="bi bi-x-lg"></i></a>
</div>
</form>
</div>
<!-- Table -->
<div class="pcard p-0">
{% if transactions %}
<table class="pfm-table">
<thead>
<tr>
<th style="padding-left:20px;">Date</th>
<th>Description</th>
<th>Category</th>
<th>Account</th>
<th class="text-end">Amount</th>
<th class="text-end" style="padding-right:20px;">Actions</th>
</tr>
</thead>
<tbody>
{% for txn in transactions %}
<tr>
<td style="padding-left:20px;font-size:12px;color:var(--muted);white-space:nowrap;">{{ txn.date.strftime('%b %d, %Y') }}</td>
<td>
<div style="font-size:13px;font-weight:500;">{{ txn.description }}</div>
{% if txn.notes %}<div style="font-size:11px;color:var(--muted);">{{ txn.notes | truncate(60) }}</div>{% endif %}
</td>
<td>
{% if txn.category %}
<span style="font-size:12px;white-space:nowrap;">
<i class="bi {{ txn.category.icon }}" style="color:{{ txn.category.color }};"></i> {{ txn.category.name }}
</span>
{% else %}<span class="text-muted" style="font-size:12px;"></span>{% endif %}
</td>
<td style="font-size:12px;color:var(--muted);">{{ txn.account.name if txn.account else '—' }}</td>
<td class="text-end mono {% if txn.transaction_type=='income' %}text-income{% else %}text-expense{% endif %}" style="font-size:13px;font-weight:600;white-space:nowrap;">
{% if txn.transaction_type=='income' %}+{% else %}-{% endif %}{{ txn.amount | currency }}
</td>
<td class="text-end" style="padding-right:20px;white-space:nowrap;">
<a href="{{ url_for('transactions.edit', id=txn.id) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;padding:2px 8px;">Edit</a>
<form method="POST" action="{{ url_for('transactions.delete', id=txn.id) }}" style="display:inline;" onsubmit="return confirm('Delete this transaction?')">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="btn btn-sm btn-outline-danger ms-1" style="font-size:11px;padding:2px 8px;">Del</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Pagination -->
{% if pagination.pages > 1 %}
<div class="d-flex justify-content-between align-items-center px-4 py-3" style="border-top:1px solid var(--border);font-size:12px;color:var(--muted);">
<span>Showing {{ ((pagination.page-1)*30)+1 }}{{ [pagination.page*30, pagination.total]|min }} of {{ pagination.total }}</span>
<div class="d-flex gap-1">
{% if pagination.has_prev %}
<a href="{{ url_for('transactions.index', tab=tab, page=pagination.prev_num, q=search, category_id=category_id, account_id=account_id, date_from=date_from, date_to=date_to) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;">← Prev</a>
{% endif %}
{% if pagination.has_next %}
<a href="{{ url_for('transactions.index', tab=tab, page=pagination.next_num, q=search, category_id=category_id, account_id=account_id, date_from=date_from, date_to=date_to) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;">Next →</a>
{% endif %}
</div>
</div>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="bi bi-inbox text-muted" style="font-size:2.5rem;"></i>
<p class="text-muted mt-2 mb-3">No {{ tab }} transactions found.</p>
<a href="{{ url_for('transactions.new', type=tab) }}" class="btn btn-sm btn-primary">Add {{ tab | title }}</a>
</div>
{% endif %}
</div>
{% endblock %}