Files
battery-tracker-app/templates/battery_detail.html
T
iterminate 3bc897c1e5 Add device_type field, mobile-friendly improvements, and device filtering
- Device model: add device_type column (String 50, nullable)
- Device add/edit: type select with presets + custom entry
- Device detail: show type in info card; new Edit Device form
- Device list: Type column + client-side filter bar (type + text search)
- Mobile: card-style responsive tables on dashboard and device list,
  form-grid-2col collapse, larger tap targets, stacked form-actions,
  column picker viewport fix, filter bar full-width controls
- Assign page: larger radio touch targets (min-height 44px)
- 3 new acceptance tests for device_type (45 total)
2026-04-12 22:02:29 -05:00

214 lines
9.1 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 %}{{ battery.label }} — Battery Tracker{% endblock %}
{% block content %}
<h1>{{ battery.label }}</h1>
{% macro meta_row(label, value) %}
{% if value %}
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">{{ label }}</td>
<td style="border:none;">{{ value }}</td>
</tr>
{% endif %}
{% endmacro %}
<div class="card">
<table style="width:auto;border:none;">
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Label</td>
<td style="border:none;">{{ battery.label }}</td>
</tr>
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Brand</td>
<td style="border:none;">{{ battery.brand }}</td>
</tr>
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Status</td>
<td style="border:none;"><span class="badge badge-{{ battery.status }}">{{ battery.status|capitalize }}</span></td>
</tr>
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Device</td>
<td style="border:none;">
{% if battery.device %}
<a href="{{ url_for('device_detail', device_id=battery.device.id) }}">{{ battery.device.name }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
</tr>
{{ meta_row("Size", battery.size) }}
{{ meta_row("Chemistry", battery.chemistry) }}
{% if battery.capacity_mah %}
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Capacity</td>
<td style="border:none;">
{{ battery.capacity_mah }} mAh
{% if battery.tested_capacity_mah %}
{% set pct = (battery.tested_capacity_mah / battery.capacity_mah * 100)|round|int %}
{% if pct >= 80 %}{% set health_color = "#166534" %}
{% elif pct >= 60 %}{% set health_color = "#92400e" %}
{% else %}{% set health_color = "#991b1b" %}
{% endif %}
&rarr; tested <strong style="color:{{ health_color }};">{{ battery.tested_capacity_mah }} mAh ({{ pct }}%)</strong>
{% if battery.tested_date %}<span class="text-muted">on {{ battery.tested_date }}</span>{% endif %}
{% endif %}
</td>
</tr>
{% elif battery.tested_capacity_mah %}
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Tested Capacity</td>
<td style="border:none;">
{{ battery.tested_capacity_mah }} mAh
{% if battery.tested_date %}<span class="text-muted">on {{ battery.tested_date }}</span>{% endif %}
</td>
</tr>
{% endif %}
{{ meta_row("Charge Cycles", battery.charge_cycles) }}
{{ meta_row("Purchase Date", battery.purchase_date) }}
{{ meta_row("Storage", battery.storage_location) }}
{% if battery.notes %}
<tr>
<td style="padding:0.3rem 1rem 0.3rem 0;font-weight:600;color:#64748b;border:none;">Notes</td>
<td style="border:none;">{{ battery.notes }}</td>
</tr>
{% endif %}
</table>
</div>
<!-- Edit Details -->
<div class="card">
<h2>Edit Details</h2>
<form method="post" action="{{ url_for('battery_edit_details', battery_id=battery.id) }}">
<div class="form-grid-2col" style="display:grid;grid-template-columns:1fr 1fr;gap:0 1rem;">
<div class="form-group">
<label>Size</label>
<select id="size-select" onchange="metaSelectChanged(this,'size')">
<option value="">— none —</option>
{% for opt in ['AA','AAA','C','D','9V','18650','21700','14500','26650','CR2032','CR123A'] %}
<option value="{{ opt }}" {% if battery.size == opt %}selected{% endif %}>{{ opt }}</option>
{% endfor %}
<option value="__new__" {% if battery.size and battery.size not in ['AA','AAA','C','D','9V','18650','21700','14500','26650','CR2032','CR123A'] %}selected{% endif %}>Other…</option>
</select>
<input type="text" id="size" name="size" value="{{ battery.size or '' }}"
placeholder="Enter size"
style="display:{% if battery.size and battery.size not in ['AA','AAA','C','D','9V','18650','21700','14500','26650','CR2032','CR123A'] %}''{% else %}none{% endif %};margin-top:0.4rem;">
</div>
<div class="form-group">
<label>Chemistry</label>
<select id="chemistry-select" onchange="metaSelectChanged(this,'chemistry')">
<option value="">— none —</option>
{% for opt in ['NiMH','Alkaline','Li-ion','LiFePO4','NiCd','Zinc-Carbon','Li-MnO2'] %}
<option value="{{ opt }}" {% if battery.chemistry == opt %}selected{% endif %}>{{ opt }}</option>
{% endfor %}
<option value="__new__" {% if battery.chemistry and battery.chemistry not in ['NiMH','Alkaline','Li-ion','LiFePO4','NiCd','Zinc-Carbon','Li-MnO2'] %}selected{% endif %}>Other…</option>
</select>
<input type="text" id="chemistry" name="chemistry" value="{{ battery.chemistry or '' }}"
placeholder="Enter chemistry"
style="display:{% if battery.chemistry and battery.chemistry not in ['NiMH','Alkaline','Li-ion','LiFePO4','NiCd','Zinc-Carbon','Li-MnO2'] %}''{% else %}none{% endif %};margin-top:0.4rem;">
</div>
<div class="form-group">
<label for="capacity_mah">Capacity (mAh)</label>
<input type="number" id="capacity_mah" name="capacity_mah" min="0"
value="{{ battery.capacity_mah or '' }}" placeholder="e.g. 2000">
</div>
<div class="form-group">
<label for="charge_cycles">Charge Cycles</label>
<input type="number" id="charge_cycles" name="charge_cycles" min="0"
value="{{ battery.charge_cycles or '' }}" placeholder="e.g. 50">
</div>
<div class="form-group">
<label for="tested_capacity_mah">Tested Capacity (mAh)</label>
<input type="number" id="tested_capacity_mah" name="tested_capacity_mah" min="0"
value="{{ battery.tested_capacity_mah or '' }}" placeholder="e.g. 1850">
</div>
<div class="form-group">
<label for="tested_date">Test Date</label>
<input type="date" id="tested_date" name="tested_date"
value="{{ battery.tested_date or '' }}">
</div>
<div class="form-group">
<label for="purchase_date">Purchase Date</label>
<input type="date" id="purchase_date" name="purchase_date"
value="{{ battery.purchase_date or '' }}">
</div>
</div>
<div class="form-group">
<label>Storage Location</label>
<select id="storage-select" onchange="metaSelectChanged(this,'storage_location')">
<option value="">— none —</option>
{% for loc in storage_locations|default([]) %}
<option value="{{ loc }}" {% if battery.storage_location == loc %}selected{% endif %}>{{ loc }}</option>
{% endfor %}
<option value="__new__" {% if battery.storage_location and battery.storage_location not in storage_locations|default([]) %}selected{% endif %}> New location…</option>
</select>
<input type="text" id="storage_location" name="storage_location"
value="{{ battery.storage_location or '' }}"
placeholder="e.g. Drawer 2, Toolbox, Shelf A"
style="display:{% if battery.storage_location and battery.storage_location not in storage_locations|default([]) %}''{% else %}none{% endif %};margin-top:0.4rem;">
</div>
<div class="form-group">
<label for="notes">Notes</label>
<textarea id="notes" name="notes" placeholder="No notes yet…">{{ battery.notes or '' }}</textarea>
</div>
<button class="btn btn-primary" type="submit">Save Details</button>
</form>
</div>
<!-- Actions -->
<div class="card">
<h2>Actions</h2>
<div class="form-actions">
{% if battery.is_available() %}
<a class="btn btn-primary" href="{{ url_for('battery_assign', battery_id=battery.id) }}">Assign to Device</a>
{% endif %}
{% if battery.is_installed() %}
<form method="post" action="{{ url_for('battery_unassign', battery_id=battery.id) }}">
<button class="btn btn-warning" type="submit">Unassign</button>
</form>
{% endif %}
{% if not battery.is_retired() %}
<form method="post" action="{{ url_for('battery_retire', battery_id=battery.id) }}">
<button class="btn btn-secondary" type="submit">Retire Battery</button>
</form>
{% else %}
<form method="post" action="{{ url_for('battery_unretire', battery_id=battery.id) }}">
<button class="btn btn-secondary" type="submit">Unretire Battery</button>
</form>
{% endif %}
<a class="btn btn-danger" href="{{ url_for('battery_delete', battery_id=battery.id) }}">Delete Battery</a>
</div>
</div>
<a class="text-muted" href="{{ url_for('dashboard') }}">&larr; Back to Dashboard</a>
<script>
function metaSelectChanged(sel, inputId) {
var input = document.getElementById(inputId);
if (sel.value === '__new__') {
input.style.display = '';
input.value = '';
input.focus();
} else {
input.style.display = 'none';
input.value = sel.value;
}
}
</script>
{% endblock %}