@javierfrancoleal/dsh-supervisor 1.0.26 → 1.0.27

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.
Files changed (2) hide show
  1. package/dashboard.html +58 -1
  2. package/package.json +1 -1
package/dashboard.html CHANGED
@@ -102,6 +102,19 @@ td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
102
102
  .row .btn{flex:1;min-width:110px}
103
103
  .switchuser{margin-top:26px;text-align:center}
104
104
  .langs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0 14px}
105
+ .langov{position:fixed;inset:0;background:linear-gradient(160deg,#4D6BFE,#7c5cff 60%,#a78bfa);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:90;animation:rise .3s ease}
106
+ .langov .top{position:absolute;top:22px;right:26px}
107
+ .langov .close{background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.3);color:#fff;border-radius:999px;width:44px;height:44px;font-size:18px;cursor:pointer}
108
+ .orow{width:min(520px,92vw);display:flex;justify-content:space-between;align-items:center;padding:15px 22px;border-radius:14px;font-size:19px;color:#fff;cursor:pointer;transition:background .15s,transform .1s}
109
+ .orow:hover{background:rgba(255,255,255,.12)}
110
+ .orow:active{transform:scale(.98)}
111
+ .orow .sub{font-size:13px;opacity:.7}
112
+ .orow.center{background:rgba(255,255,255,.30);font-size:23px;font-weight:800;border:1px solid rgba(255,255,255,.45)}
113
+ .orow.center .sub{opacity:.9}
114
+ .langreel{width:min(340px,86vw);height:58px;margin:10px auto;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.30);border-radius:10px;backdrop-filter:blur(8px);overflow:hidden;cursor:pointer;position:relative;box-shadow:0 10px 30px rgba(15,23,42,.15)}
115
+ body.dark .langreel{background:rgba(20,31,49,.55)}
116
+ .ticks{display:flex;flex-direction:column;will-change:transform}
117
+ .tick{height:58px;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;opacity:.85;color:#fff}
105
118
  .pill{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 13px;font-size:13px;cursor:pointer}
106
119
  .pill.active{background:var(--blue);color:#fff;border-color:var(--blue)}
107
120
  .person{background:var(--card2);border:1px solid var(--line);border-radius:16px;padding:14px;margin:10px 0}
@@ -161,6 +174,10 @@ body.wall pre{max-height:40vh}
161
174
  <button class="btn small gray" id="logoutBtn" style="display:none">Log out</button>
162
175
  </header>
163
176
  <main>
177
+ <div id="langOverlay" class="langov hidden" style="display:none">
178
+ <div class="top"><button class="close" id="closeOverlay">✕</button></div>
179
+ <div id="langRows"></div>
180
+ </div>
164
181
  <div id="loginView" class="card" style="max-width:440px;margin:26px auto">
165
182
  <div class="loginbrand">
166
183
  <div class="mark" style="background:none;box-shadow:none"><svg width="64" height="64" viewBox="0 0 64 64" aria-hidden="true"><defs><linearGradient id="osgd" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#4D6BFE"/><stop offset="1" stop-color="#7c5cff"/></linearGradient></defs><path pathLength="100" d="M10 32 C10 22 16 14 32 14 C48 14 54 22 54 32 C54 42 48 50 32 50 C20 50 12.5 45.2 10.5 38.5 C14 42.5 20 41 25.4 34.8 A6.6 6.6 0 0 1 38.6 34.8 C38.6 31.4 36.6 28.2 32 22.5 C27.4 28.2 25.4 31.4 25.4 34.8" fill="none" stroke="url(#osgd)" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
@@ -168,7 +185,7 @@ body.wall pre{max-height:40vh}
168
185
  <p id="tagline">The AI works. The human decides.</p>
169
186
  </div>
170
187
  <h2 id="loginTitle" style="font-size:14px;color:var(--muted);text-align:center">Log in</h2>
171
- <div id="langs" class="langs"></div>
188
+ <div class="langreel" id="langReel"><div class="ticks" id="langTicks"></div></div>
172
189
  <input id="loginUser" placeholder="User" autocomplete="username">
173
190
  <div class="passwrap">
174
191
  <input id="loginPass" type="password" placeholder="Password" autocomplete="current-password">
@@ -496,6 +513,46 @@ function applyLang(){
496
513
  panelLinks();
497
514
  reRenderDynamic();
498
515
  }
516
+ const LANGNAMES={es:"Español",en:"English",fr:"Français",de:"Deutsch",it:"Italiano",pt:"Português",zh:"中文",ja:"日本語",ko:"한국어",ar:"العربية"};
517
+ const LANGORDER=["it","zh","de","es","en","fr","ja","pt","ko","ar"];
518
+ function buildLangMenu(){
519
+ const rows=$("langRows");
520
+ for(const l of LANGORDER){
521
+ const r=document.createElement("div");
522
+ r.className="orow"+(l==="en"?" center":"");
523
+ r.innerHTML='<span>'+LANGNAMES[l]+'</span><span class="sub">'+l.toUpperCase()+'</span>';
524
+ r.onclick=()=>{cur=l;applyLang();$("langOverlay").style.display="none";markReel();};
525
+ rows.appendChild(r);
526
+ }
527
+ }
528
+ function markReel(){
529
+ document.querySelectorAll("#langTicks .tick").forEach(t=>t.classList.toggle("active",t.dataset.l===cur));
530
+ }
531
+ function buildReel(){
532
+ for(let pass=0;pass<2;pass++){
533
+ for(const l of Object.keys(LANG)){
534
+ const d=document.createElement("div");
535
+ d.className="tick";d.dataset.l=l;d.textContent=LANGNAMES[l];
536
+ $("langTicks").appendChild(d);
537
+ }
538
+ }
539
+ const N=Object.keys(LANG).length,H=58,CYCLE=20000;
540
+ const t0=performance.now();
541
+ (function frame(now){
542
+ const t=(now-t0)%CYCLE;
543
+ $("langTicks").style.transform="translateY(-"+((t/CYCLE)*N*H)+"px)";
544
+ requestAnimationFrame(frame);
545
+ })(t0);
546
+ }
547
+ buildLangMenu();
548
+ buildReel();
549
+ markReel();
550
+ $("langReel").onclick=()=>{$("langOverlay").style.display="flex";const en=document.querySelector("#langRows .center");if(en)en.scrollIntoView({block:"center"});};
551
+ $("closeOverlay").onclick=()=>{$("langOverlay").style.display="none";};
552
+ // The Apple flow: after the splash, the language menu opens once (until chosen).
553
+ setTimeout(()=>{
554
+ try{if(!localStorage.getItem("dsh-lang")){$("langOverlay").style.display="flex";}}catch(e){}
555
+ },1600);
499
556
  function pill(l){for(const host of ["langs","footLangs"]){const b=document.createElement("button");b.className="pill";b.dataset.l=l;b.textContent=LANG[l];b.onclick=()=>{cur=l;applyLang();};$(host).appendChild(b);}}
500
557
  for(const l of Object.keys(LANG))pill(l);
501
558
  try{const q=new URLSearchParams(location.search);const ql=q.get("lang");if(ql&&S[ql])cur=ql;}catch(e){}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@javierfrancoleal/dsh-supervisor",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
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",