Files
Personal-Finance-Management/app/templates/utilities/bills.html
T

144 lines
7.4 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 %}Utility Bills{% endblock %}
{% block page_title %}Utility Bills{% endblock %}
{% block extra_css %}
.util-chip { font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: 10px; text-transform: uppercase; letter-spacing: .05em; }
{% endblock %}
{% block topbar_actions %}
<a href="{{ url_for('utilities.index') }}" class="btn btn-sm btn-outline-secondary" style="font-size:12px;">← Utilities</a>
<a href="{{ url_for('utilities.bill_new') }}" class="btn btn-sm btn-primary" style="font-size:12px;"><i class="bi bi-plus-lg me-1"></i><span class="btn-label">New Bill</span></a>
{% endblock %}
{% block content %}
<!-- Filters -->
<div class="pcard mb-3">
<form method="GET" class="row g-2 align-items-end">
<div class="col-6 col-md-3">
<label class="form-label fw-medium" style="font-size:12px;">Provider</label>
<select name="provider_id" class="form-select form-select-sm">
<option value="">All providers</option>
{% for p in providers %}
<option value="{{ p.id }}" {% if provider_id == p.id %}selected{% endif %}>{{ p.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label fw-medium" style="font-size:12px;">Type</label>
<select name="utility_type" class="form-select form-select-sm">
<option value="">All types</option>
{% for key, meta in type_meta.items() %}
<option value="{{ key }}" {% if utility_type == key %}selected{% endif %}>{{ meta[0] }}</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label fw-medium" style="font-size:12px;">Status</label>
<select name="status" class="form-select form-select-sm">
<option value="">All</option>
<option value="unpaid" {% if status == 'unpaid' %}selected{% endif %}>Unpaid</option>
<option value="overdue" {% if status == 'overdue' %}selected{% endif %}>Overdue</option>
<option value="paid" {% if status == 'paid' %}selected{% endif %}>Paid</option>
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label fw-medium" style="font-size:12px;">Year</label>
<select name="year" class="form-select form-select-sm">
<option value="">All years</option>
{% for y in years %}
<option value="{{ y }}" {% if year == y %}selected{% endif %}>{{ y }}</option>
{% endfor %}
</select>
</div>
<div class="col-12 col-md-3 d-flex gap-2">
<button type="submit" class="btn btn-sm btn-primary" style="font-size:12px;"><i class="bi bi-funnel me-1"></i>Filter</button>
<a href="{{ url_for('utilities.bills') }}" class="btn btn-sm btn-outline-secondary" style="font-size:12px;">Clear</a>
</div>
</form>
</div>
{% if bills %}
<div class="pcard p-0">
<div class="table-wrap">
<table class="pfm-table wide">
<thead>
<tr>
<th>Provider</th>
<th>Period</th>
<th class="d-mob-none">Due</th>
<th class="text-end">Amount</th>
<th class="text-end d-mob-none">Usage</th>
<th>Status</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
{% for b in bills %}
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div style="width:28px;height:28px;border-radius:7px;background:{{ b.provider.color }}22;color:{{ b.provider.color }};display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;">
<i class="bi {{ b.provider.icon }}"></i>
</div>
<div>
<a href="{{ url_for('utilities.provider_detail', id=b.provider_id) }}" style="font-size:13px;font-weight:600;text-decoration:none;color:inherit;">{{ b.provider.name }}</a>
<div style="font-size:11px;color:var(--muted);">{{ b.provider.type_label }}</div>
</div>
</div>
</td>
<td style="font-size:12px;">{{ b.period_label }}</td>
<td class="d-mob-none" style="font-size:12px;">{{ b.due_date.strftime('%b %d, %Y') if b.due_date else '—' }}</td>
<td class="text-end mono fw-bold" style="font-size:13px;">{{ b.amount | currency }}</td>
<td class="text-end mono d-mob-none" style="font-size:12px;">
{% if b.usage %}{{ '%.1f' | format(b.usage | float) }} <span style="color:var(--muted);">{{ b.usage_unit or '' }}</span>{% else %}—{% endif %}
</td>
<td>
{% if b.status == 'paid' %}
<span class="util-chip" style="background:#d1fae5;color:#065f46;">Paid</span>
{% elif b.status == 'overdue' %}
<span class="util-chip" style="background:#fee2e2;color:#991b1b;">{{ b.days_until_due | abs }}d late</span>
{% elif b.status == 'due_soon' %}
<span class="util-chip" style="background:#fef3c7;color:#92400e;">Due in {{ b.days_until_due }}d</span>
{% else %}
<span class="util-chip" style="background:#f1f5f9;color:#475569;">Unpaid</span>
{% endif %}
</td>
<td class="text-end">
{% if not b.is_paid %}
<a href="{{ url_for('utilities.bill_pay', id=b.id) }}" class="btn btn-sm btn-primary" style="font-size:11px;padding:3px 10px;">Pay</a>
{% endif %}
<a href="{{ url_for('utilities.bill_edit', id=b.id) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;padding:3px 8px;"><i class="bi bi-pencil"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if pagination.pages > 1 %}
<div class="d-flex justify-content-between align-items-center p-3" style="border-top:1px solid var(--border);font-size:12px;color:var(--muted);">
<span>Page {{ pagination.page }} of {{ pagination.pages }} &nbsp;·&nbsp; {{ ((pagination.page-1)*30)+1 }}{{ [pagination.page*30, pagination.total]|min }} of {{ pagination.total }}</span>
<div class="d-flex gap-2">
{% if pagination.has_prev %}
<a href="{{ url_for('utilities.bills', page=pagination.prev_num, provider_id=provider_id, utility_type=utility_type, status=status, year=year) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;">← Prev</a>
{% endif %}
{% if pagination.has_next %}
<a href="{{ url_for('utilities.bills', page=pagination.next_num, provider_id=provider_id, utility_type=utility_type, status=status, year=year) }}" class="btn btn-sm btn-outline-secondary" style="font-size:11px;">Next →</a>
{% endif %}
</div>
</div>
{% endif %}
</div>
{% else %}
<div class="pcard text-center py-5">
<i class="bi bi-receipt text-muted" style="font-size:3rem;"></i>
<h5 class="mt-3 mb-1">No bills match</h5>
<p class="text-muted small mb-3">Try clearing the filters, or record a new bill.</p>
<a href="{{ url_for('utilities.bill_new') }}" class="btn btn-primary btn-sm">New Bill</a>
</div>
{% endif %}
{% endblock %}