mirror of
https://github.com/samsonjs/spirit-tracker.git
synced 2026-03-25 09:25:51 +00:00
UX Improvements
This commit is contained in:
parent
ae0cf44e98
commit
f88cd290c3
2 changed files with 43 additions and 32 deletions
|
|
@ -206,31 +206,17 @@ export async function renderStore($app, storeLabelRaw) {
|
|||
|
||||
function dateMsFromRow(r) {
|
||||
if (!r) return null;
|
||||
const keys = [
|
||||
"firstSeenAt",
|
||||
"firstSeen",
|
||||
"createdAt",
|
||||
"created",
|
||||
"addedAt",
|
||||
"added",
|
||||
"date",
|
||||
"ts",
|
||||
"timestamp",
|
||||
];
|
||||
for (const k of keys) {
|
||||
const v = r[k];
|
||||
if (v === undefined || v === null) continue;
|
||||
if (typeof v === "number" && Number.isFinite(v)) {
|
||||
// If seconds-ish, normalize to ms
|
||||
if (v > 0 && v < 2e10) return v < 2e9 ? v * 1000 : v;
|
||||
return v;
|
||||
}
|
||||
if (typeof v === "string") {
|
||||
const t = Date.parse(v);
|
||||
if (Number.isFinite(t)) return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
// Match renderItem() semantics:
|
||||
// 1) prefer precise ts
|
||||
const t = String(r?.ts || "");
|
||||
const ms = t ? Date.parse(t) : NaN;
|
||||
if (Number.isFinite(ms)) return ms;
|
||||
|
||||
// 2) fall back to date-only (treat as end of day UTC so ordering within day is stable)
|
||||
const d = String(r?.date || "");
|
||||
const ms2 = d ? Date.parse(d + "T23:59:59Z") : NaN;
|
||||
return Number.isFinite(ms2) ? ms2 : null;
|
||||
}
|
||||
|
||||
// Build earliest "first in DB" timestamp per canonical SKU (includes removed rows)
|
||||
|
|
@ -715,10 +701,24 @@ export async function renderStore($app, storeLabelRaw) {
|
|||
});
|
||||
|
||||
$clearSearch.addEventListener("click", () => {
|
||||
if (!$q.value) return;
|
||||
$q.value = "";
|
||||
localStorage.setItem(LS_KEY, "");
|
||||
applyFilter();
|
||||
let changed = false;
|
||||
|
||||
if ($q.value) {
|
||||
$q.value = "";
|
||||
localStorage.setItem(LS_KEY, "");
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// reset max price too (only if slider is active)
|
||||
if (pageMax !== null) {
|
||||
selectedMaxPrice = clampAndRound(boundMax);
|
||||
localStorage.setItem(LS_MAX_PRICE, String(selectedMaxPrice));
|
||||
setSliderFromPrice(selectedMaxPrice);
|
||||
updateMaxPriceLabel();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) applyFilter();
|
||||
$q.focus();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -255,12 +255,23 @@ a.skuLink:hover { text-decoration: underline; cursor: pointer; }
|
|||
background: #0f1318;
|
||||
color: var(--muted);
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
|
||||
/* custom arrow (puts it a bit left from the edge) */
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa6b2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 10px center;
|
||||
background-size: 12px 12px;
|
||||
|
||||
padding: 6px 28px 6px 10px; /* right padding reserves room for arrow */
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
.selectSmall:hover {
|
||||
border-color: #2f3a46;
|
||||
color: var(--text);
|
||||
|
|
|
|||
Loading…
Reference in a new issue