Stonks/overview/templates/portfolio.html

134 lines
6.1 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ account.name }}{% endblock %}
{% block content %}
<div class="section-panel">
<div class="d-flex flex-column flex-lg-row justify-content-between align-items-lg-end gap-3">
<div>
<h1 class="h2 mb-2">{{ account.name }}</h1>
<p class="text-secondary mb-0">{{ account.provider|default:"manual" }}{% if account.number %} • {{ account.number }}{% endif %}</p>
</div>
<div class="text-lg-end">
<div class="metric-label">Current Balance</div>
<div class="metric-value">${{ account.balance }}</div>
</div>
</div>
</div>
<div class="row g-4 mb-4">
<div class="col-12 col-lg-8">
<section class="section-panel h-100">
<div class="d-flex justify-content-between align-items-start mb-3">
<div>
<h2 class="h5 mb-1">Account Value Over Time</h2>
<p class="text-secondary mb-0">Historical balance snapshots recorded each time this account is synced.</p>
</div>
</div>
<div class="d-flex justify-content-between align-items-end gap-3 flex-wrap mb-3">
{% if latest_account_point %}
<div class="text-end">
<div class="metric-label">Latest Snapshot</div>
<div class="fw-semibold fs-5">${{ latest_account_point.display_value }}</div>
</div>
{% endif %}
<form method="get" class="range-form">
<label for="account-range" class="metric-label mb-0">Range</label>
<select id="account-range" name="range" class="form-select form-select-sm range-select" onchange="this.form.submit()">
{% for value, label in date_range_options %}
<option value="{{ value }}"{% if selected_range == value %} selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</form>
</div>
{% if account_timeline %}
<div class="chart-frame">
<div class="chart-axis chart-axis-top">
<span>${{ account_chart.max_label }}</span>
<span>Change shown on hover</span>
</div>
<svg class="chart-svg" viewBox="0 0 100 100" preserveAspectRatio="none" role="img" aria-label="Account value over time">
<line class="chart-baseline" x1="0" y1="100" x2="100" y2="100"></line>
<path class="chart-line" d="{{ account_chart.path }}"></path>
{% for point in account_chart.points %}
<circle class="chart-point" cx="{{ point.x }}" cy="{{ point.y }}" r="2.2">
<title>{{ point.label }} | ${{ point.display_value }} | {{ point.change_display }}</title>
</circle>
{% endfor %}
</svg>
<div class="chart-axis chart-axis-bottom">
<span>{{ account_chart.start_label }}</span>
<span>${{ account_chart.min_label }}</span>
<span>{{ account_chart.end_label }}</span>
</div>
</div>
{% else %}
<p class="text-secondary mb-0">No account history yet. Run another sync to capture snapshots.</p>
{% endif %}
</section>
</div>
<div class="col-12 col-lg-4">
<section class="section-panel h-100">
<h2 class="h5 mb-3">Snapshot Timeline</h2>
{% if account_timeline %}
<div class="list-group list-group-flush timeline-list">
{% for point in account_timeline %}
<div class="list-group-item">
<div class="d-flex justify-content-between gap-3">
<span class="text-secondary">{{ point.label }}</span>
<strong>${{ point.display_value }}</strong>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-secondary mb-0">No snapshot points available yet.</p>
{% endif %}
</section>
</div>
</div>
<section class="section-panel">
<div class="d-flex justify-content-between align-items-center mb-3">
<h2 class="h5 mb-0">Current Holdings</h2>
<span class="text-secondary small">{{ holdings|length }} position{{ holdings|length|pluralize }}</span>
</div>
<div class="list-group">
<div class="list-group-item">
<div class="row align-items-center">
<div class="col-3"><strong>Ticker</strong></div>
<div class="col-3"><strong>Value</strong></div>
<div class="col-3"><strong>Amount</strong></div>
<div class="col-3"><strong>Cost Basis</strong></div>
</div>
</div>
{% for holding in holdings %}
<div class="list-group-item">
<div class="row align-items-center">
<div class="col-3">
<strong>{{ holding.asset.ticker }}</strong>
</div>
<div class="col-3">
${{ holding.holding_value|floatformat:2 }}
<div class="small text-secondary">${{ holding.holding_gain|floatformat:2 }}</div>
</div>
<div class="col-3">
{{ holding.ammount|floatformat:4 }}
</div>
<div class="col-3">
${{ holding.cost_basis|floatformat:2 }}
</div>
</div>
</div>
{% empty %}
<div class="list-group-item">
<p class="text-secondary mb-0">No holdings available for this account.</p>
</div>
{% endfor %}
</div>
</section>
{% endblock %}