mirror of
https://github.com/samsonjs/spirit-tracker.git
synced 2026-04-27 15:07:43 +00:00
UX Improvements
This commit is contained in:
parent
ae0cf44e98
commit
f88cd290c3
2 changed files with 43 additions and 32 deletions
|
|
@ -206,33 +206,19 @@ export async function renderStore($app, storeLabelRaw) {
|
||||||
|
|
||||||
function dateMsFromRow(r) {
|
function dateMsFromRow(r) {
|
||||||
if (!r) return null;
|
if (!r) return null;
|
||||||
const keys = [
|
|
||||||
"firstSeenAt",
|
// Match renderItem() semantics:
|
||||||
"firstSeen",
|
// 1) prefer precise ts
|
||||||
"createdAt",
|
const t = String(r?.ts || "");
|
||||||
"created",
|
const ms = t ? Date.parse(t) : NaN;
|
||||||
"addedAt",
|
if (Number.isFinite(ms)) return ms;
|
||||||
"added",
|
|
||||||
"date",
|
// 2) fall back to date-only (treat as end of day UTC so ordering within day is stable)
|
||||||
"ts",
|
const d = String(r?.date || "");
|
||||||
"timestamp",
|
const ms2 = d ? Date.parse(d + "T23:59:59Z") : NaN;
|
||||||
];
|
return Number.isFinite(ms2) ? ms2 : null;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build earliest "first in DB" timestamp per canonical SKU (includes removed rows)
|
// Build earliest "first in DB" timestamp per canonical SKU (includes removed rows)
|
||||||
const firstSeenBySku = new Map(); // sku -> ms
|
const firstSeenBySku = new Map(); // sku -> ms
|
||||||
for (const r of listingsAll) {
|
for (const r of listingsAll) {
|
||||||
|
|
@ -715,13 +701,27 @@ export async function renderStore($app, storeLabelRaw) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$clearSearch.addEventListener("click", () => {
|
$clearSearch.addEventListener("click", () => {
|
||||||
if (!$q.value) return;
|
let changed = false;
|
||||||
$q.value = "";
|
|
||||||
localStorage.setItem(LS_KEY, "");
|
if ($q.value) {
|
||||||
applyFilter();
|
$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();
|
$q.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
$exSort.addEventListener("change", () => {
|
$exSort.addEventListener("change", () => {
|
||||||
localStorage.setItem(LS_EX_SORT, String($exSort.value || ""));
|
localStorage.setItem(LS_EX_SORT, String($exSort.value || ""));
|
||||||
applyFilter();
|
applyFilter();
|
||||||
|
|
|
||||||
|
|
@ -255,12 +255,23 @@ a.skuLink:hover { text-decoration: underline; cursor: pointer; }
|
||||||
background: #0f1318;
|
background: #0f1318;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
border-radius: 999px;
|
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;
|
font-size: 12px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.selectSmall:hover {
|
.selectSmall:hover {
|
||||||
border-color: #2f3a46;
|
border-color: #2f3a46;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue