From cba339151f50801a63cbe35b2f7d15b58e18c0b7 Mon Sep 17 00:00:00 2001 From: type-two Date: Tue, 23 Jun 2026 10:51:41 +1000 Subject: [PATCH] =?UTF-8?q?feat(nav):=20Crate=20Info=20panel=20=E2=80=94?= =?UTF-8?q?=20edit=20label=5Ftext=20+=20rotate=20crate.direction=20in=20/s?= =?UTF-8?q?earch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per-crate panel under Crate Contents: rename (label_text) + a Facing segment (↑back/↓front/←left/→right) that rotates the crate live — the map arrow flips on click. CrateEditIn gained 'direction'. Restores the crate editing my tabbed rewrite dropped. Co-Authored-By: Claude Opus 4.8 --- app/navigator_routes.py | 1 + site/search.html | 42 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/navigator_routes.py b/app/navigator_routes.py index 24d020e..be2c8b0 100644 --- a/app/navigator_routes.py +++ b/app/navigator_routes.py @@ -156,6 +156,7 @@ class CrateEditIn(BaseModel): name: str | None = None label_text: str | None = None crate_purpose: str | None = None + direction: str | None = None # forward | back | left | right — the crate's facing (rotate) @router.post("/crate/{crate_id}") diff --git a/site/search.html b/site/search.html index 7ff4136..5614674 100644 --- a/site/search.html +++ b/site/search.html @@ -112,6 +112,18 @@
pick a crate on the map →
+
💿 Release Info
@@ -194,7 +206,7 @@ function redraw(){ if(ST.view==='store') drawStore(); else if(ST.rack) drawRack( // ───────────── STORE VIEW ───────────── async function toStore(){ - ST.view='store'; ST.rack=null; ST.selCrate=null; + ST.view='store'; ST.rack=null; ST.selCrate=null; ST.crateInfo=null; renderCrateInfo(); $('#lvlCtl').style.display='none'; $('#rackEditBtn').style.display='none'; $('#crumb').textContent='Store map'; const sid=$('#spaceSel').value; @@ -317,9 +329,35 @@ async function loadCrate(id){ ${esc(i.artist||'')}${esc(i.genre||'')}${i.style?' · '+esc(i.style):''} ${money(i.price)}`).join('')+'' : '
empty crate
'; - setViewBtns(); + setViewBtns(); renderCrateInfo(); if(ST.tab==='scanner') renderScanner(); } +function renderCrateInfo(){ + const c=ST.crateInfo, p=$('#crateInfoPanel'); if(!p) return; + if(!c){ p.style.display='none'; return; } + p.style.display=''; + $('#ciName').value=c.label_text||c.name||''; + const d=(c.direction||'').toLowerCase(); + document.querySelectorAll('#ciFacing button').forEach(b=>b.classList.toggle('on', b.dataset.d===d)); + $('#ciSaved').textContent=''; +} +async function crateRotate(dir){ + if(!ST.selCrate) return; + await post('/nav/crate/'+ST.selCrate,{direction:dir}); + ST.crateInfo.direction=dir; + const c=(ST.crates||[]).find(x=>x.id===ST.selCrate); if(c) c.direction=dir; + renderCrateInfo(); redraw(); // facing arrow flips live on the map + $('#ciSaved').textContent='✓ rotated'; +} +async function crateRename(){ + if(!ST.selCrate) return; + const v=$('#ciName').value.trim(); + await post('/nav/crate/'+ST.selCrate,{label_text:v}); + ST.crateInfo.label_text=v; + const c=(ST.crates||[]).find(x=>x.id===ST.selCrate); if(c) c.label_text=v; + $('#ccName').innerHTML='📦 '+esc(v||('Crate '+ST.selCrate)); + $('#ciSaved').textContent='✓ saved'; redraw(); // crate label updates on the map +} async function compressCrate(id){ if(!confirm('Renumber this crate\'s slots 1..N (close gaps)?')) return; await fetch('/nav/reorg/compress/'+id,{method:'POST',headers:hdr()}); loadCrate(id);