You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
5.3 KiB
HTML
120 lines
5.3 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>SplitBuddy</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
<script defer src="{{ url_for('static', filename='app.js') }}"></script>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<header>
|
|
<div class="h1">SplitBuddy</div>
|
|
<div>
|
|
<span class="pill {{ 'bad' if summary.total>0 else ('ok' if summary.total<0 else '') }}">
|
|
{% if summary.total > 0 %}
|
|
{{ A }} owes {{ B }} <strong>{{ currency }}{{ '%.2f'|format(summary.total) }}</strong>
|
|
{% elif summary.total < 0 %}
|
|
{{ B }} owes {{ A }} <strong>{{ currency }}{{ '%.2f'|format(-summary.total) }}</strong>
|
|
{% else %}All settled ✨{% endif %}
|
|
</span>
|
|
<span class="pill muted">Balance: {{ currency }}{{ '%.2f'|format(summary.total) }}</span>
|
|
<a class="pill" href="{{ url_for('export_csv') }}">Export CSV</a>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="grid">
|
|
<section class="card">
|
|
<h2>Add entry</h2>
|
|
<form method="post" action="{{ url_for('add') }}">
|
|
<div class="row">
|
|
<div class="seg" title="Entry type">
|
|
<input type="radio" id="k_bill" name="kind" value="bill" checked><label for="k_bill">Bill</label>
|
|
<input type="radio" id="k_xfer" name="kind" value="transfer"><label for="k_xfer">Transfer</label>
|
|
</div>
|
|
<div class="toggle" title="Who paid / who sent">
|
|
<input type="radio" id="payer_a" name="payer" value="A" checked><label for="payer_a">{{ A }}</label>
|
|
<input type="radio" id="payer_b" name="payer" value="B"><label for="payer_b">{{ B }}</label>
|
|
</div>
|
|
<input type="number" step="0.0001" min="0" name="total" placeholder="Amount" required>
|
|
<select name="method">
|
|
<option>cash</option><option>transfer</option><option>other</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="row" id="share-wrap" style="margin-top:8px">
|
|
<input id="a_share" type="number" step="0.0001" min="0" max="100" name="a_share_pct"
|
|
placeholder="{{ A }} share %" value="{{ '%.4f'|format(default_a_share_pct) }}"
|
|
title="{{ A }}'s share (%)">
|
|
<input type="text" name="note" placeholder="Reason (e.g. rent, groceries, washer)" style="flex:1">
|
|
<input type="datetime-local" name="created_at" value="{{ now_local }}">
|
|
<button class="btn" type="submit">Add</button>
|
|
</div>
|
|
|
|
<div class="row" id="presets" style="margin-top:8px">
|
|
<div class="seg" title="Quick presets">
|
|
<input type="radio" id="p50" name="preset"><label for="p50">50/50</label>
|
|
<input type="radio" id="p66" name="preset" checked><label for="p66">{{ A }} 2/3</label>
|
|
<input type="radio" id="p33" name="preset"><label for="p33">{{ A }} 1/3</label>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="card">
|
|
<h2>Stats</h2>
|
|
<div class="muted">Entries: {{ summary.count }}</div>
|
|
<div class="muted">Latest: {{ summary.latest or '—' }}</div>
|
|
<div style="margin-top:8px">
|
|
<span class="tag">Cash Δ: {{ currency }}{{ '%.2f'|format(summary.by_method.cash) }}</span>
|
|
<span class="tag">Transfer Δ: {{ currency }}{{ '%.2f'|format(summary.by_method.transfer) }}</span>
|
|
<span class="tag">Other Δ: {{ currency }}{{ '%.2f'|format(summary.by_method.other) }}</span>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<section class="card" style="margin-top:16px">
|
|
<h2>Ledger</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width:160px">Time</th>
|
|
<th>Type</th>
|
|
<th>Payer/Sender</th>
|
|
<th>Reason</th>
|
|
<th>Method</th>
|
|
<th class="num">Your share %</th>
|
|
<th class="num">Amount</th>
|
|
<th class="num">Δ Balance</th>
|
|
<th style="width:120px"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for e in entries %}
|
|
<tr>
|
|
<td>{{ e.created_at }}</td>
|
|
<td>{{ e.kind }}</td>
|
|
<td>{{ A if e.payer=='A' else B }}</td>
|
|
<td>{{ e.note or '—' }}</td>
|
|
<td>{{ e.method }}</td>
|
|
<td class="num">{{ e.kind == 'bill' and ('%.2f'|format(e.a_share*100) ~ '%') or '—' }}</td>
|
|
<td class="num">{{ currency }}{{ '%.2f'|format(e.total) }}</td>
|
|
<td class="num {{ 'pos' if e.delta>0 else 'neg' if e.delta<0 else '' }}">
|
|
{{ currency }}{{ '%.2f'|format(e.delta) }}
|
|
</td>
|
|
<td>
|
|
<form method="post" action="{{ url_for('delete', entry_id=e.id) }}" onsubmit="return confirm('Delete this entry?');">
|
|
<button class="btn danger" type="submit">Delete</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
</div>
|
|
</body>
|
|
</html> |