226 lines
8.3 KiB
HTML
226 lines
8.3 KiB
HTML
{% extends "base.html" %}
|
||
{% block content %}
|
||
<div class="page-header">
|
||
<h1>Net Worth</h1>
|
||
<span class="muted" style="font-size:0.85rem;">Assets minus Liabilities</span>
|
||
</div>
|
||
|
||
<!-- Big Net Worth Number -->
|
||
<div class="net-worth-hero {% if net_worth >= 0 %}net-worth-positive{% else %}net-worth-negative{% endif %}">
|
||
<div class="net-worth-label">Current Net Worth</div>
|
||
<div class="net-worth-number">${{ net_worth | money }}</div>
|
||
<div class="net-worth-sub">
|
||
<span>Assets: <strong>${{ total_assets | money }}</strong></span>
|
||
<span style="margin:0 0.75rem;opacity:0.5;">−</span>
|
||
<span>Debts: <strong>${{ total_debts | money }}</strong></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;margin-top:1.5rem;">
|
||
|
||
<!-- ASSETS COLUMN -->
|
||
<div>
|
||
<h2 style="margin-bottom:1rem;color:var(--accent);">Assets</h2>
|
||
|
||
<!-- Cash & Accounts -->
|
||
<div class="budget-section">
|
||
<div class="budget-section-header" style="border-left-color:#7AB87A;">
|
||
<h3>Cash & Bank Accounts</h3>
|
||
<span class="muted" style="font-size:0.82rem;">${{ total_cash | money }}</span>
|
||
</div>
|
||
<table class="budget-table">
|
||
<thead><tr><th>Account</th><th>Owner</th><th>Balance</th><th></th></tr></thead>
|
||
<tbody>
|
||
{% for acc in accounts %}
|
||
<tr>
|
||
<td>{{ acc.name }}</td>
|
||
<td><span class="owner-tag" style="background:{{ owner_colors.get(acc.owner,'#ddd') }};font-size:0.72rem;">{{ acc.owner }}</span></td>
|
||
<td class="amount">
|
||
<input type="number" step="0.01" class="budget-input"
|
||
value="{{ acc.balance }}"
|
||
onchange="updateAccount('{{ acc.id }}', this.value)"
|
||
style="width:110px;">
|
||
</td>
|
||
<td>
|
||
<form method="POST" action="/net-worth/account/delete/{{ acc.id }}" style="display:inline;">
|
||
<button type="submit" class="debt-delete-btn" onclick="return confirm('Remove this account?')">✕</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="total-row">
|
||
<td colspan="2">Total Cash</td>
|
||
<td class="amount">${{ total_cash | money }}</td>
|
||
<td></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
|
||
<!-- Add Account -->
|
||
<details style="margin-top:0.75rem;">
|
||
<summary class="btn btn-ghost" style="display:inline-block;cursor:pointer;font-size:0.82rem;">+ Add Account</summary>
|
||
<form method="POST" action="/net-worth/account/add" style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-top:0.75rem;align-items:flex-end;">
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.78rem;">Account Name</label>
|
||
<input type="text" name="name" placeholder="e.g. WestConsin Checking" class="budget-input" required>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.78rem;">Owner</label>
|
||
<select name="owner" class="budget-input">
|
||
<option value="Bonna">Bonna</option>
|
||
<option value="Tony">Tony</option>
|
||
<option value="Both">Both</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.78rem;">Balance</label>
|
||
<input type="number" step="0.01" name="balance" placeholder="0.00" class="budget-input" style="width:110px;">
|
||
</div>
|
||
<button type="submit" class="btn btn-primary" style="align-self:flex-end;">Add</button>
|
||
</form>
|
||
</details>
|
||
</div>
|
||
|
||
<!-- Sinking Funds -->
|
||
<div class="budget-section" style="margin-top:1rem;">
|
||
<div class="budget-section-header" style="border-left-color:#C5BBA0;">
|
||
<h3>Sinking Funds</h3>
|
||
<a href="{{ url_for('sinking_view') }}" class="edit-link">manage</a>
|
||
<span class="muted" style="font-size:0.82rem;">${{ total_sinking | money }}</span>
|
||
</div>
|
||
<table class="budget-table">
|
||
<tbody>
|
||
{% for f in sinking_funds %}
|
||
<tr>
|
||
<td>{{ f.name }}</td>
|
||
<td class="amount">${{ (f.balance or 0) | money }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="total-row">
|
||
<td>Total</td>
|
||
<td class="amount">${{ total_sinking | money }}</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Vehicles -->
|
||
{% if personal_cars %}
|
||
<div class="budget-section" style="margin-top:1rem;">
|
||
<div class="budget-section-header" style="border-left-color:#D4A96A;">
|
||
<h3>Vehicles</h3>
|
||
<a href="{{ url_for('assets_view') }}" class="edit-link">manage</a>
|
||
<span class="muted" style="font-size:0.82rem;">${{ total_vehicles | money }}</span>
|
||
</div>
|
||
<table class="budget-table">
|
||
<tbody>
|
||
{% for car in personal_cars %}
|
||
<tr>
|
||
<td>{{ car.display_name }}</td>
|
||
<td><span class="owner-tag" style="background:{{ owner_colors.get(car.owner,'#ddd') }};font-size:0.72rem;">{{ car.owner }}</span></td>
|
||
<td class="amount">
|
||
{% if car.estimated_value %}
|
||
${{ car.estimated_value | float | money }}
|
||
{% else %}
|
||
<span class="muted">no value set</span>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="total-row">
|
||
<td colspan="2">Total</td>
|
||
<td class="amount">${{ total_vehicles | money }}</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- Other Assets -->
|
||
{% if other_assets %}
|
||
<div class="budget-section" style="margin-top:1rem;">
|
||
<div class="budget-section-header" style="border-left-color:#A08CC5;">
|
||
<h3>Other Assets</h3>
|
||
<a href="{{ url_for('assets_view') }}" class="edit-link">manage</a>
|
||
<span class="muted" style="font-size:0.82rem;">${{ total_other_assets | money }}</span>
|
||
</div>
|
||
<table class="budget-table">
|
||
<tbody>
|
||
{% for a in other_assets %}
|
||
<tr>
|
||
<td>{{ a.name }}</td>
|
||
<td class="muted" style="font-size:0.8rem;">{{ a.category }}</td>
|
||
<td class="amount">${{ a.value | float | money }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="total-row">
|
||
<td colspan="2">Total</td>
|
||
<td class="amount">${{ total_other_assets | money }}</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
{% endif %}
|
||
|
||
</div><!-- end assets column -->
|
||
|
||
<!-- LIABILITIES COLUMN -->
|
||
<div>
|
||
<h2 style="margin-bottom:1rem;color:#C57A7A;">Liabilities (Debts)</h2>
|
||
|
||
{% for cat in debt_categories %}
|
||
{% set cat_debts = debts_by_cat[cat] %}
|
||
{% if cat_debts %}
|
||
<div class="budget-section" style="margin-top:{% if loop.first %}0{% else %}1rem{% endif %};">
|
||
<div class="budget-section-header" style="border-left-color:#C57A7A;">
|
||
<h3>{{ cat }}</h3>
|
||
<span class="muted" style="font-size:0.82rem;">${{ debt_cat_totals[cat] | money }}</span>
|
||
</div>
|
||
<table class="budget-table">
|
||
<tbody>
|
||
{% for d in cat_debts %}
|
||
<tr>
|
||
<td>{{ d.name }}</td>
|
||
<td><span class="owner-tag" style="background:{{ owner_colors.get(d.owner,'#ddd') }};font-size:0.72rem;">{{ d.owner }}</span></td>
|
||
<td class="amount">${{ d.current_balance | float | money }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="total-row">
|
||
<td colspan="2">Subtotal</td>
|
||
<td class="amount">${{ debt_cat_totals[cat] | money }}</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
|
||
<div class="leftover-bar" style="margin-top:1rem;">
|
||
<span>Total Debt</span>
|
||
<span style="font-size:1.1rem;font-weight:700;color:#C57A7A;">${{ total_debts | money }}</span>
|
||
</div>
|
||
</div><!-- end liabilities column -->
|
||
|
||
</div>
|
||
|
||
<script>
|
||
function updateAccount(id, value) {
|
||
fetch('/net-worth/account/update/' + id, {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||
body: new URLSearchParams({balance: value})
|
||
}).then(() => location.reload());
|
||
}
|
||
</script>
|
||
{% endblock %}
|