@javierfrancoleal/dsh-supervisor 1.0.45 → 1.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dashboard.html CHANGED
@@ -178,6 +178,26 @@ body.wall{background:linear-gradient(165deg,#0b1220 0%,#131c30 60%,#1e1b4b 100%)
178
178
  body.firstboot header,body.firstboot main,body.firstboot footer{display:none}
179
179
  body.wall pre{max-height:40vh}
180
180
  @media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
181
+
182
+ /* ── Mobile-first pass (2026-11-03) — the owner's dashboard on phones ── */
183
+ @media(max-width:560px){
184
+ .card{padding:12px;margin:8px 0;border-radius:16px}
185
+ header{padding:10px 12px;gap:6px}
186
+ header h1{font-size:15px}
187
+ .metrics{grid-template-columns:repeat(2,1fr);gap:8px}
188
+ .metric{padding:10px 8px}
189
+ .metric .v{font-size:20px}
190
+ .row{flex-direction:column;align-items:stretch}
191
+ .row>*{margin:0 0 6px}
192
+ input,select,textarea{font-size:16px}
193
+ table{display:block;overflow-x:auto;white-space:nowrap}
194
+ .order{flex-wrap:wrap;gap:4px}
195
+ .wall-grid{grid-template-columns:repeat(2,1fr);gap:10px}
196
+ .langstep-inner svg{width:120px;height:120px}
197
+ #loginView{margin:16px auto;padding:14px}
198
+ .langov .orow{padding:12px 16px;font-size:17px}
199
+ .orow.center{font-size:20px}
200
+ }
181
201
  </style>
182
202
  </head>
183
203
  <body>
@@ -557,7 +577,7 @@ function buildLangMenu(){
557
577
  const r=document.createElement("div");
558
578
  r.className="orow"+(l==="en"?" center":"");
559
579
  r.innerHTML='<span>'+LANGNAMES[l]+'</span><span class="sub">'+l.toUpperCase()+'</span>';
560
- r.onclick=()=>{cur=l;try{localStorage.setItem("dsh-lang",cur);}catch(e){}applyLang();$("langOverlay").style.display="none";markReel();$("langStep").style.display="none";const sp=$("splash");sp.classList.remove("done");const p=sp.querySelector("svg path");if(p){p.style.animation="none";void p.offsetWidth;p.style.animation="";}const tag=$("splashTag");if(tag){tag.textContent=t("tagline");}setTimeout(()=>{$("loginView").style.display="";document.body.classList.remove("firstboot");},2100);setTimeout(()=>{sp.classList.add("done");},2600);};
580
+ r.onclick=()=>{cur=l;try{localStorage.setItem("dsh-lang",cur);}catch(e){}applyLang();$("langOverlay").style.display="none";markReel();$("langStep").style.display="none";bootFlash(2600,()=>{$("loginView").style.display="";document.body.classList.remove("firstboot");});};
561
581
  rows.appendChild(r);
562
582
  }
563
583
  }
@@ -587,6 +607,15 @@ $("langStepReel").onclick=()=>{$("langOverlay").style.display="flex";const en=do
587
607
  $("closeOverlay").onclick=()=>{$("langOverlay").style.display="none";};
588
608
  // The Apple flow: after the splash, the language menu opens once (until chosen).
589
609
 
610
+ function bootFlash(ms,then){
611
+ const sp=$("splash");
612
+ sp.style.display="flex";
613
+ sp.classList.remove("done");
614
+ const p=sp.querySelector("svg path");
615
+ if(p){p.style.animation="none";void p.offsetWidth;p.style.animation="";}
616
+ const tag=$("splashTag");if(tag){tag.textContent=t("tagline");}
617
+ setTimeout(()=>{sp.classList.add("done");if(then)then();},ms);
618
+ }
590
619
  function pill(l){for(const host of ["footLangs"]){const el=$(host);if(!el)continue;const b=document.createElement("button");b.className="pill";b.dataset.l=l;b.textContent=LANG[l];b.onclick=()=>{cur=l;try{localStorage.setItem("dsh-lang",cur);}catch(e){}applyLang();};$(host).appendChild(b);}}
591
620
  for(const l of Object.keys(LANG))pill(l);
592
621
  try{const q=new URLSearchParams(location.search);const ql=q.get("lang");if(ql&&S[ql])cur=ql;}catch(e){}
@@ -702,7 +731,7 @@ $("setupBtn").onclick=async()=>{
702
731
  if(r.error){$("setupBtn").disabled=false;$("setupBtn").textContent=t("setupBtn");toast(String(r.error).indexOf("already")>=0?t("loginFailed"):r.error);return;}
703
732
  token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
704
733
  sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
705
- enter();
734
+ bootFlash(1400,()=>enter());
706
735
  };
707
736
  $("loginBtn").onclick=async()=>{
708
737
  const err=$("loginError");
@@ -716,9 +745,9 @@ $("loginBtn").onclick=async()=>{
716
745
  err.classList.add("hidden");
717
746
  token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
718
747
  sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
719
- $("loginPass").value="";enter();
748
+ $("loginPass").value="";bootFlash(1400,()=>enter());
720
749
  };
721
- function logout(){api("/api/logout",{});token=null;me=null;sessionStorage.clear();if(livePoll)clearInterval(livePoll);if(kitchenPoll)clearInterval(kitchenPoll);setWho();show("loginView");}
750
+ function logout(){api("/api/logout",{});token=null;me=null;sessionStorage.clear();if(livePoll)clearInterval(livePoll);if(kitchenPoll)clearInterval(kitchenPoll);setWho();bootFlash(1200,()=>show("loginView"));}
722
751
  $("logoutBtn").onclick=logout;
723
752
  const sb=$("switchBtn");if(sb)sb.onclick=logout;
724
753
  async function loadUsers(){const tb=$("usersTable").querySelector("tbody");tb.innerHTML='<tr><td colspan="2">'+skel(2)+'</td></tr>';const r=await api("/api/users");tb.innerHTML="";(r.users||[]).forEach(u=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+esc(u.name)+"</td><td>"+esc(u.label||u.name)+" · "+t(LVL[u.role]||"lvlEmployee")+"</td>";tb.appendChild(tr);});}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@javierfrancoleal/dsh-supervisor",
3
- "version": "1.0.45",
3
+ "version": "1.0.47",
4
4
  "description": "The Veilleux central control plane of the J.Franco agentic workflow suite: user accounts, the live conversation flow (listen → per-person summary → confirm → orders), telemetry, and the universal sector dashboard with 10 languages. Created by J.Franco.",
5
5
  "author": "J.Franco",
6
6
  "license": "MIT",
package/server.js CHANGED
@@ -44,7 +44,7 @@ const LIVE_FILE = path.join(DATA_DIR, "live.json");
44
44
  const SECTOR_FILE = path.join(DATA_DIR, "sector.json");
45
45
  const REG_FILE = path.join(DATA_DIR, "register.json");
46
46
  const PRICE_PER_MILLION = Number(process.env.DSH_PRICE_PER_MILLION || 0.28);
47
- const VERSION = "1.0.44";
47
+ const VERSION = "1.0.47";
48
48
  // Homeostasis: the daily token budget (metabolic limit). The brain rests
49
49
  // when the budget is spent — no runaway costs.
50
50
  const DAILY_BUDGET_USD = Number(process.env.DSH_DAILY_BUDGET_USD || 0); // 0 = unlimited: consumption is the business