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 โ
+
+
๐ฆ Crate Info
+
+
Facing
+
+
+
+
+
+
+
+
@@ -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);