@javierfrancoleal/dsh-supervisor 0.0.0-stage โ 1.0.0
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/README.md +40 -2
- package/bin/jfranco-supervisor.js +11 -0
- package/dashboard.html +460 -0
- package/icons/icons/apple-icon-180.png +0 -0
- package/icons/icons/icon-192.png +0 -0
- package/icons/icons/icon-512.png +0 -0
- package/manifest.webmanifest +17 -0
- package/package.json +41 -4
- package/panel.html +383 -0
- package/sector-packs/sector-packs/clinic.json +83 -0
- package/sector-packs/sector-packs/hotel.json +83 -0
- package/sector-packs/sector-packs/pharmacy.json +99 -0
- package/sector-packs/sector-packs/realestate.json +99 -0
- package/sector-packs/sector-packs/restaurant.json +83 -0
- package/sector-packs/sector-packs/school.json +99 -0
- package/sector-packs/sector-packs/workshop.json +99 -0
- package/server.js +429 -0
package/dashboard.html
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="theme-color" content="#4D6BFE">
|
|
7
|
+
<title>Supervisor โ J.Franco Suite</title>
|
|
8
|
+
<style>
|
|
9
|
+
:root{--blue:#4D6BFE;--green:#22c55e;--amber:#facc15;--red:#ef4444;--ink:#101828;--muted:#667085;--bg:#f6f7fb;--card:#fff;--card2:var(--card2);--line:var(--line);--line2:var(--line2)}
|
|
10
|
+
body.dark{--ink:#e6ecf7;--muted:#94a3b8;--bg:#0b1220;--card:#141f31;--card2:#18253a;--line:#26334d;--line2:#26334d}
|
|
11
|
+
.anim{animation:slidein .28s ease}
|
|
12
|
+
@keyframes slidein{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
|
|
13
|
+
.empty{text-align:center;padding:26px 12px;color:var(--muted);font-size:14px;border:1px dashed var(--line);border-radius:14px}
|
|
14
|
+
.empty .ico{font-size:30px;display:block;margin-bottom:6px}
|
|
15
|
+
*{box-sizing:border-box}
|
|
16
|
+
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:var(--bg);color:var(--ink);-webkit-tap-highlight-color:transparent}
|
|
17
|
+
header{background:var(--blue);color:#fff;padding:12px 16px;display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
|
|
18
|
+
header h1{margin:0;font-size:18px}
|
|
19
|
+
header .who{font-size:13px;opacity:.9}
|
|
20
|
+
button{font-family:inherit;cursor:pointer}
|
|
21
|
+
.btn{border:none;border-radius:12px;padding:12px 16px;font-size:15px;font-weight:600;color:#fff;background:var(--blue)}
|
|
22
|
+
.btn.gray{background:var(--line2);color:var(--ink)}
|
|
23
|
+
.btn.small{padding:8px 12px;font-size:13px}
|
|
24
|
+
main{max-width:960px;margin:0 auto;padding:14px}
|
|
25
|
+
.card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:16px;margin:12px 0}
|
|
26
|
+
.card h2{margin:0 0 10px;font-size:16px}
|
|
27
|
+
input,select,textarea{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;font-size:16px;margin-bottom:8px;font-family:inherit;background:var(--card)}
|
|
28
|
+
textarea{resize:vertical;min-height:80px}
|
|
29
|
+
pre{background:#0f172a;color:#d7e3f4;border-radius:12px;padding:12px;font-size:12.5px;overflow:auto;max-height:320px;white-space:pre-wrap;margin:0}
|
|
30
|
+
.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px}
|
|
31
|
+
.metric{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:12px;text-align:center}
|
|
32
|
+
.metric .v{font-size:26px;font-weight:700;color:var(--blue)}
|
|
33
|
+
.metric .l{font-size:12px;color:var(--muted);margin-top:2px}
|
|
34
|
+
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
|
|
35
|
+
.tabs button{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:10px 16px;font-size:15px;font-weight:600}
|
|
36
|
+
.tabs button.active{background:var(--blue);color:#fff;border-color:var(--blue)}
|
|
37
|
+
table{width:100%;border-collapse:collapse;font-size:14px}
|
|
38
|
+
td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
|
|
39
|
+
.hidden{display:none}
|
|
40
|
+
.kban{background:#fef3c7;border:1px solid #f59e0b;color:#92400e;border-radius:12px;padding:12px 14px;margin:10px 0;font-weight:700;font-size:15px}
|
|
41
|
+
.chip{background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.35);border-radius:999px;padding:5px 12px;font-size:13px;font-weight:600}
|
|
42
|
+
.foot{text-align:center;padding:6px 16px 16px}
|
|
43
|
+
.foot .copyr{font-size:12px;color:var(--muted)}
|
|
44
|
+
.eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;font-size:18px;cursor:pointer;padding:4px}
|
|
45
|
+
.passwrap{position:relative}
|
|
46
|
+
.loginerr{background:#fee2e2;color:#b91c1c;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
|
|
47
|
+
.loginok{background:#dcfce7;color:#15803d;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
|
|
48
|
+
.note{color:var(--muted);font-size:13px}
|
|
49
|
+
.hint{font-size:12.5px;color:var(--muted);margin-top:4px}
|
|
50
|
+
.listen{display:block;width:100%;border:none;border-radius:24px;padding:34px 16px;font-size:28px;font-weight:800;color:#fff;background:var(--green);box-shadow:0 6px 20px rgba(34,197,94,.4);margin:14px 0}
|
|
51
|
+
.listen:active{transform:scale(.98)}
|
|
52
|
+
.listen.pulse{animation:pulse 1.6s infinite}
|
|
53
|
+
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(34,197,94,.55)}70%{box-shadow:0 0 0 26px rgba(34,197,94,0)}100%{box-shadow:0 0 0 0 rgba(34,197,94,0)}}
|
|
54
|
+
.stopbtn{background:var(--red)!important;box-shadow:0 6px 20px rgba(239,68,68,.35)!important}
|
|
55
|
+
.row{display:flex;gap:8px;flex-wrap:wrap}
|
|
56
|
+
.row .btn{flex:1;min-width:110px}
|
|
57
|
+
.switchuser{margin-top:26px;text-align:center}
|
|
58
|
+
.langs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0 14px}
|
|
59
|
+
.pill{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 13px;font-size:13px;cursor:pointer}
|
|
60
|
+
.pill.active{background:var(--blue);color:#fff;border-color:var(--blue)}
|
|
61
|
+
.person{background:var(--card2);border:1px solid var(--line);border-radius:16px;padding:14px;margin:10px 0}
|
|
62
|
+
.person .pname{font-size:17px;font-weight:700;margin-bottom:8px}
|
|
63
|
+
.req{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card);border:1px solid var(--line2);margin:6px 0}
|
|
64
|
+
.req .txt{flex:1;font-size:15px}
|
|
65
|
+
.req .tier{font-size:12px;font-weight:700;padding:4px 8px;border-radius:999px}
|
|
66
|
+
.tier-GREEN{background:#dcfce7;color:#15803d}
|
|
67
|
+
.tier-SEMI{background:#fef9c3;color:#a16207}
|
|
68
|
+
.tier-YELLOW{background:#fef9c3;color:#a16207}
|
|
69
|
+
.tier-RED{background:#fee2e2;color:#b91c1c}
|
|
70
|
+
.confirmBtn{background:var(--blue);color:#fff;border:none;border-radius:12px;padding:10px 14px;font-size:14px;font-weight:700;white-space:nowrap}
|
|
71
|
+
.confirmBtn.done{background:#dcfce7;color:#15803d}
|
|
72
|
+
.order{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card2);border:1px solid var(--line);margin:6px 0;font-size:14px}
|
|
73
|
+
.order .stat{font-size:12px;font-weight:700;padding:4px 10px;border-radius:999px;background:#e0e7ff;color:#3730a3}
|
|
74
|
+
#wallView{max-width:1100px}
|
|
75
|
+
.wall-head{font-size:34px;font-weight:800;color:#fff;text-align:center;margin:10px 0}
|
|
76
|
+
.wall-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
|
|
77
|
+
.wall-card{background:#1b2436;color:#fff;border-radius:16px;padding:20px;text-align:center}
|
|
78
|
+
.wall-card .v{font-size:44px;font-weight:800}
|
|
79
|
+
.wall-card .l{font-size:15px;opacity:.85}
|
|
80
|
+
body.wall{background:#0b1220}
|
|
81
|
+
body.wall pre{max-height:40vh}
|
|
82
|
+
@media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
|
|
83
|
+
</style>
|
|
84
|
+
</head>
|
|
85
|
+
<body>
|
|
86
|
+
<header>
|
|
87
|
+
<h1 id="appTitle">๐ข Supervisor ยท J.Franco Suite</h1>
|
|
88
|
+
<span class="who" id="who"></span>
|
|
89
|
+
<span class="chip" id="idChip" style="display:none"></span>
|
|
90
|
+
<button class="btn small gray" id="darkBtn">๐</button>
|
|
91
|
+
<button class="btn small gray" id="soundBtn">๐</button>
|
|
92
|
+
<button class="btn small gray" id="logoutBtn" style="display:none">Log out</button>
|
|
93
|
+
</header>
|
|
94
|
+
<main>
|
|
95
|
+
<div id="loginView" class="card" style="max-width:440px;margin:26px auto">
|
|
96
|
+
<h2 id="loginTitle">Log in</h2>
|
|
97
|
+
<div id="langs" class="langs"></div>
|
|
98
|
+
<input id="loginUser" placeholder="User" autocomplete="username">
|
|
99
|
+
<div class="passwrap">
|
|
100
|
+
<input id="loginPass" type="password" placeholder="Password" autocomplete="current-password">
|
|
101
|
+
<button class="eye" id="eyeBtn" type="button" aria-label="Show password"><svg id="eyeOn" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg><svg id="eyeOff" class="hidden" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg></button>
|
|
102
|
+
</div>
|
|
103
|
+
<div id="loginError" class="loginerr hidden"></div>
|
|
104
|
+
<button class="btn" id="loginBtn" style="width:100%">Log in</button>
|
|
105
|
+
<p class="hint" id="loginHint">Accounts are managed by the business owner.</p>
|
|
106
|
+
<a href="/dashboard?wall=1"><button class="btn gray small" id="openWall" style="width:100%;margin-top:6px">Live wallboard</button></a>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div id="ownerView" class="hidden">
|
|
110
|
+
<div class="metrics" id="ownerMetrics"></div>
|
|
111
|
+
<div class="tabs">
|
|
112
|
+
<button data-tab="overview" class="active" id="tabOverview">Overview</button>
|
|
113
|
+
<button data-tab="field" id="tabField">Field</button>
|
|
114
|
+
<button data-tab="rules" id="tabRules">Rules</button>
|
|
115
|
+
<button data-tab="sector" id="tabSector">Sector</button>
|
|
116
|
+
</div>
|
|
117
|
+
<div id="tab-overview">
|
|
118
|
+
<div class="card"><h2 id="workersTitle">Workers</h2>
|
|
119
|
+
<table id="usersTable"><thead><tr><th id="thUser">User</th><th id="thRole">Role</th></tr></thead><tbody></tbody></table>
|
|
120
|
+
<h2 style="margin-top:14px" id="addWorkerTitle">Add worker</h2>
|
|
121
|
+
<div id="suggestUsers" class="row"></div>
|
|
122
|
+
<input id="newUser" placeholder="User name"><input id="newPass" type="password" placeholder="Password">
|
|
123
|
+
<input id="newLabel" placeholder="Role label (e.g. Cook)">
|
|
124
|
+
<select id="newRole"><option id="optEmployee" value="employee">employee</option><option id="optLead" value="lead">lead</option><option id="optOwner" value="owner">owner</option></select>
|
|
125
|
+
<button class="btn" id="addUserBtn">Add worker</button>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="card"><h2 id="ordersTitle">Orders โ kitchen & bill</h2><div id="ownerOrders"></div></div>
|
|
128
|
+
<div class="card"><h2 id="usageTitle">Usage & cost</h2><p class="hint" id="usageSub">(per worker, estimated)</p>
|
|
129
|
+
<table id="usageTable"><thead><tr><th id="thWorker">Worker</th><th id="thSessions">Sessions</th><th id="thTokens">Tokens</th><th id="thCost">Est. cost</th></tr></thead><tbody></tbody></table>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="card"><h2 id="panelTitle">Action Panel</h2><p class="note" id="panelNote">Workers open the panel from their tablet or phone.</p>
|
|
132
|
+
<a href="/panel" target="_blank" id="openPanelLink"><button class="btn" id="openPanel">Open Action Panel</button></a>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div id="tab-field" class="hidden">
|
|
136
|
+
<div class="card"><h2 id="fieldReportsTitle">Field reports</h2>
|
|
137
|
+
<div class="row" style="margin-bottom:8px"><button class="btn small gray" id="refreshReports">Refresh</button><button class="btn small gray" id="autoRefresh">Auto-refresh: OFF</button></div>
|
|
138
|
+
<pre id="reports"></pre>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="card"><h2 id="trailTitle">Conversation trail</h2><p class="hint" id="trailHint">The raw phrases captured from the field, in order.</p><pre id="trail"></pre></div>
|
|
141
|
+
<div class="card"><h2 id="feedbackTitle">Feedback queue</h2><pre id="feedback"></pre>
|
|
142
|
+
<p class="hint" id="feedbackHint">The agent reads this queue and resolves errors and improvements.</p>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<div id="tab-sector" class="hidden">
|
|
146
|
+
<div class="card"><h2 id="sectorPresetsTitle">Sector presets</h2><div id="presetGrid" class="row"></div></div>
|
|
147
|
+
<div class="card">
|
|
148
|
+
<h2 id="customSectorTitle">Custom sector</h2>
|
|
149
|
+
<input id="csId" placeholder="id (e.g. bakery)">
|
|
150
|
+
<input id="csLabelEn" placeholder="Label (EN)"><input id="csLabelFr" placeholder="Label (FR)">
|
|
151
|
+
<input id="csOrdersEn" placeholder="Orders title (EN)"><input id="csOrdersFr" placeholder="Orders title (FR)">
|
|
152
|
+
<input id="csF1Id" placeholder="Field 1 id (e.g. orderNo)"><input id="csF1Label" placeholder="Field 1 label (EN)">
|
|
153
|
+
<input id="csF2Id" placeholder="Field 2 id (optional)"><input id="csF2Label" placeholder="Field 2 label (EN)">
|
|
154
|
+
<button class="btn" id="saveSectorBtn">Save sector</button>
|
|
155
|
+
<button class="btn gray" id="aiSectorBtn" style="margin-top:6px">Suggest with AI (copy prompt)</button>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
<div id="tab-rules" class="hidden">
|
|
159
|
+
<div class="card"><h2 id="rulesTitle">Business rules</h2><p class="hint" id="rulesHint">These rules train the traffic light.</p>
|
|
160
|
+
<textarea id="decisions" rows="14"></textarea>
|
|
161
|
+
<button class="btn" id="saveDecisions">Save rules</button><span id="decisionsSaved" class="note"></span>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div id="leadView" class="hidden">
|
|
167
|
+
<div class="metrics" id="leadMetrics"></div>
|
|
168
|
+
<div id="kitchenBanner" class="kban hidden"></div>
|
|
169
|
+
<div class="card"><h2 id="leadOrdersTitle">Orders โ kitchen & bill</h2>
|
|
170
|
+
<button class="btn small gray" id="notifBtn" style="margin-bottom:8px">๐ Enable notifications</button>
|
|
171
|
+
<p class="hint" id="notifHint">The kitchen tablet beeps and flashes when an order arrives.</p>
|
|
172
|
+
<div id="leadOrders"></div></div>
|
|
173
|
+
<div class="card"><h2 id="leadReportsTitle">Field reports</h2><button class="btn small gray" id="leadRefresh">Refresh</button><pre id="leadReports"></pre></div>
|
|
174
|
+
<div class="card"><h2 id="leadFeedbackTitle">Feedback queue</h2><pre id="leadFeedback"></pre></div>
|
|
175
|
+
<div class="card"><a href="/panel" target="_blank" id="leadOpenPanelLink"><button class="btn" id="leadOpenPanel">Open Action Panel</button></a></div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<div id="employeeView" class="hidden">
|
|
179
|
+
<div id="wHome">
|
|
180
|
+
<div class="card" style="text-align:center;padding:8px"><h2 id="workerHi" style="margin:0"></h2></div>
|
|
181
|
+
<input id="tableInput" placeholder="Table #" style="margin:8px 0">
|
|
182
|
+
<div id="packFields" class="row"></div>
|
|
183
|
+
<button class="listen" id="startBtn">โถ START</button>
|
|
184
|
+
<div class="card"><h2 id="reportTitle">Field report</h2><textarea id="reportText" rows="4" placeholder="What happened on your shift?"></textarea><button class="btn" id="reportBtn">Send report</button></div>
|
|
185
|
+
<div class="card"><h2 id="fbTitle">Field feedback</h2>
|
|
186
|
+
<select id="empFbCat"><option value="error">Error</option><option value="improvement">Improvement</option><option value="idea">Idea</option></select>
|
|
187
|
+
<textarea id="empFbText" rows="3" placeholder="What happened? What should improve?"></textarea><button class="btn" id="empFbBtn">Send feedback</button>
|
|
188
|
+
</div>
|
|
189
|
+
<div class="switchuser"><button class="btn small gray" id="switchBtn">Switch user</button></div>
|
|
190
|
+
</div>
|
|
191
|
+
<div id="wListen" class="hidden">
|
|
192
|
+
<button class="listen pulse" id="listeningBtn">๐๏ธ</button>
|
|
193
|
+
<div class="card" style="text-align:center"><h2 id="listeningText">Listeningโฆ speak now</h2><p class="note" id="listeningHint">The conversation is being captured and split by person.</p></div>
|
|
194
|
+
<div class="card">
|
|
195
|
+
<textarea id="sayText" rows="3" placeholder="What did they say?"></textarea>
|
|
196
|
+
<div class="row">
|
|
197
|
+
<button class="btn" id="sayBtn">Send phrase</button>
|
|
198
|
+
<button class="btn gray" id="micBtn">๐๏ธ Dictate</button>
|
|
199
|
+
</div>
|
|
200
|
+
<p class="hint" id="aiHint">Speech and text go straight to the AI โ the summary appears automatically.</p>
|
|
201
|
+
</div>
|
|
202
|
+
<button class="listen stopbtn" id="stopBtn">โน Stop listening</button>
|
|
203
|
+
</div>
|
|
204
|
+
<div id="wSummary" class="hidden">
|
|
205
|
+
<div class="card" style="text-align:center"><h2 id="summaryTitle">Conversation summary</h2></div>
|
|
206
|
+
<div id="summaryBody"></div>
|
|
207
|
+
<div class="card"><h2 id="ordersTitle2">Orders โ kitchen & bill</h2><div id="workerOrders"></div></div>
|
|
208
|
+
<div class="row" style="margin:12px 0">
|
|
209
|
+
<button class="btn" id="newConvBtn">New conversation</button>
|
|
210
|
+
<button class="btn gray" id="toHomeBtn">Back</button>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div id="wallView" class="hidden">
|
|
216
|
+
<div class="wall-head" id="wallHead">๐ญ J.Franco Suite โ Live</div>
|
|
217
|
+
<div class="wall-grid" id="wallCards"></div>
|
|
218
|
+
<div class="card" style="margin-top:14px"><h2 style="color:#fff" id="wallPulseTitle">Field pulse</h2><pre id="wallFeed"></pre></div>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div id="msg" class="note" style="text-align:center"></div>
|
|
222
|
+
</main>
|
|
223
|
+
<footer class="foot"><div class="langs" id="footLangs"></div><div class="copyr">Suite J.Franco ยท open source (MIT) ยท autor J.Franco</div></footer>
|
|
224
|
+
<script>
|
|
225
|
+
"use strict";
|
|
226
|
+
const LANG={es:"ES",en:"EN",fr:"FR",de:"DE",it:"IT",pt:"PT",zh:"ไธญๆ",ja:"ๆฅๆฌ่ช",ko:"ํ๊ตญ์ด",ar:"ุงูุนุฑุจูุฉ"};
|
|
227
|
+
const S={
|
|
228
|
+
en:{login:"Log in",user:"User",password:"Password",loginBtn:"Log in",loginHint:"Accounts are managed by the business owner.",loginFailed:"Login failed.",cannotReach:"Cannot reach the supervisor server. Is it running?",workerAdded:"Worker added.",saved:"Saved.",reportSent:"Report sent.",feedbackSent:"Feedback sent.",wallOpen:"Live wallboard",logout:"Log out",overview:"Overview",field:"Field",rules:"Rules",reports:"Reports",week:"This week",feedback:"Feedback",workersActive:"Workers active",reportsTotal:"Reports total",workers:"Workers",thUser:"User",thRole:"Role",addWorker:"Add worker",userName:"User name",addBtn:"Add worker",usage:"Usage & cost",usageSub:"(per worker, estimated)",thWorker:"Worker",thSessions:"Sessions",thTokens:"Tokens",thCost:"Est. cost",panel:"Action Panel",panelNote:"Workers open the panel from their tablet or phone.",openPanel:"Open Action Panel",fieldReports:"Field reports",feedbackQueue:"Feedback queue",feedbackHint:"The agent reads this queue and resolves errors and improvements.",refresh:"Refresh",autoOn:"Auto-refresh: ON",autoOff:"Auto-refresh: OFF",rulesTitle:"Business rules",rulesHint:"These rules train the traffic light.",saveRules:"Save rules",listen:"๐๏ธ LISTEN",hi:"๐ ",reportTitle:"Field report",reportPh:"What happened on your shift?",sendReport:"Send report",fbTitle:"Field feedback",fbPh:"What happened? What should improve?",sendFeedback:"Send feedback",switchUser:"Switch user",wallHead:"๐ญ J.Franco Suite โ Live",wallPulse:"Field pulse",noActivity:"(no field activity yet)",start:"โถ START",listening:"Listeningโฆ speak now",listeningHint:"The conversation is being captured and split by person.",stopListening:"โน Stop listening",summaryTitle:"Conversation summary",confirm:"Confirm โ",confirmed:"Confirmed โ",sentNote:"Sent to kitchen & central",newConv:"New conversation",ordersTitle:"Orders โ kitchen & bill",person:"Person",noSummary:"The summary will appear here as the conversation is detected.",prep:"Preparing",ready:"Ready",delivered:"Delivered",sent:"Sent",back:"Back",sayPh:"Speak or type what each person saidโฆ",sendPhrase:"Send phrase",dictate:"๐๏ธ Dictate",aiHint:"Speech and text go straight to the AI โ the summary appears automatically.",micUnsupported:"Dictation not supported in this browser",processing:"The AI is summarizingโฆ",sectorTab:"Sector",sectorPresets:"Sector presets",customSector:"Custom sector",saveSector:"Save sector",sectorSaved:"Sector saved.",aiSuggest:"Suggest with AI (copy prompt)",aiSectorCopied:"AI prompt copied โ paste it in DeepSeek Harness.",fillBoth:"Enter your user and password.",loggingIn:"Logging inโฆ",noOrders:"No orders yet โ confirm items in the summary.",noUsage:"No usage reported yet.",noReports:"No field reports yet.",lvlEmployee:"Field",lvlLead:"Supervisor",lvlOwner:"Owner",labelPh:"Role label (e.g. Cook)",newOrder:"NEW ORDER",enableNotif:"๐ Enable notifications",notifHint:"The kitchen tablet beeps and flashes when an order arrives."},
|
|
229
|
+
es:{login:"Iniciar sesiรณn",user:"Usuario",password:"Contraseรฑa",loginBtn:"Entrar",loginHint:"Las cuentas las gestiona el dueรฑo del negocio.",loginFailed:"Datos incorrectos.",cannotReach:"No se puede contactar el servidor. ยฟEstรก corriendo?",workerAdded:"Trabajador aรฑadido.",saved:"Guardado.",reportSent:"Reporte enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Wallboard en vivo",logout:"Salir",overview:"Resumen",field:"Campo",rules:"Reglas",reports:"Reportes",week:"Esta semana",feedback:"Feedback",workersActive:"Trabajadores activos",reportsTotal:"Reportes totales",workers:"Trabajadores",thUser:"Usuario",thRole:"Rol",addWorker:"Aรฑadir trabajador",userName:"Nombre de usuario",addBtn:"Aรฑadir trabajador",usage:"Uso y coste",usageSub:"(por trabajador, estimado)",thWorker:"Trabajador",thSessions:"Sesiones",thTokens:"Tokens",thCost:"Coste est.",panel:"Panel de Acciรณn",panelNote:"Los trabajadores abren el panel desde su tablet o telรฉfono.",openPanel:"Abrir Panel de Acciรณn",fieldReports:"Reportes de campo",feedbackQueue:"Cola de feedback",feedbackHint:"El agente lee esta cola y resuelve errores y mejoras.",refresh:"Actualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Reglas del negocio",rulesHint:"Estas reglas entrenan el semรกforo.",saveRules:"Guardar reglas",listen:"๐๏ธ ESCUCHAR",hi:"๐ ",reportTitle:"Reporte de campo",reportPh:"ยฟQuรฉ pasรณ en tu turno?",sendReport:"Enviar reporte",fbTitle:"Feedback de campo",fbPh:"ยฟQuรฉ pasรณ? ยฟQuรฉ debe mejorar?",sendFeedback:"Enviar feedback",switchUser:"Cambiar de usuario",wallHead:"๐ญ Suite J.Franco โ En vivo",wallPulse:"Pulso del campo",noActivity:"(sin actividad de campo aรบn)",start:"โถ INICIAR",listening:"Escuchandoโฆ habla ahora",listeningHint:"La conversaciรณn se captura y divide por persona.",stopListening:"โน Detener",summaryTitle:"Resumen de la conversaciรณn",confirm:"Confirmar โ",confirmed:"Confirmado โ",sentNote:"Enviado a cocina y central",newConv:"Nueva conversaciรณn",ordersTitle:"Pedidos โ cocina y cuenta",person:"Persona",noSummary:"El resumen aparecerรก aquรญ conforme se detecta la conversaciรณn.",prep:"Preparando",ready:"Listo",delivered:"Entregado",sent:"Enviado",back:"Volver",sayPh:"Habla o escribe lo que dijo cada personaโฆ",sendPhrase:"Enviar frase",dictate:"๐๏ธ Dictar",aiHint:"Voz y texto van directo a la IA โ el resumen aparece solo.",micUnsupported:"Dictado no soportado en este navegador",processing:"La IA estรก resumiendoโฆ",sectorTab:"Sector",sectorPresets:"Sectores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar sector",sectorSaved:"Sector guardado.",aiSuggest:"Sugerir con IA (copiar prompt)",aiSectorCopied:"Prompt de IA copiado โ pรฉgalo en DeepSeek Harness.",fillBoth:"Escribe tu usuario y contraseรฑa.",loggingIn:"Entrandoโฆ",noOrders:"Aรบn no hay pedidos โ confirma elementos en el resumen.",noUsage:"Aรบn no hay uso reportado.",noReports:"Aรบn no hay reportes de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dueรฑo",labelPh:"Etiqueta de rol (ej. Cocinero)",newOrder:"NUEVO PEDIDO",enableNotif:"๐ Activar notificaciones",notifHint:"La tablet de cocina suena y parpadea cuando llega un pedido."},
|
|
230
|
+
fr:{login:"Connexion",user:"Utilisateur",password:"Mot de passe",loginBtn:"Se connecter",loginHint:"Les comptes sont gรฉrรฉs par le propriรฉtaire.",loginFailed:"รchec de connexion.",cannotReach:"Serveur injoignable. Est-il lancรฉ ?",workerAdded:"Employรฉ ajoutรฉ.",saved:"Enregistrรฉ.",reportSent:"Rapport envoyรฉ.",feedbackSent:"Feedback envoyรฉ.",wallOpen:"Tableau en direct",logout:"Dรฉconnexion",overview:"Vue d'ensemble",field:"Terrain",rules:"Rรจgles",reports:"Rapports",week:"Cette semaine",feedback:"Feedback",workersActive:"Employรฉs actifs",reportsTotal:"Total rapports",workers:"Employรฉs",thUser:"Utilisateur",thRole:"Rรดle",addWorker:"Ajouter un employรฉ",userName:"Nom d'utilisateur",addBtn:"Ajouter",usage:"Usage et coรปt",usageSub:"(par employรฉ, estimรฉ)",thWorker:"Employรฉ",thSessions:"Sessions",thTokens:"Jetons",thCost:"Coรปt est.",panel:"Panneau d'action",panelNote:"Les employรฉs ouvrent le panneau depuis leur tablette ou tรฉlรฉphone.",openPanel:"Ouvrir le panneau",fieldReports:"Rapports terrain",feedbackQueue:"File de feedback",feedbackHint:"L'agent lit cette file et rรฉsout erreurs et amรฉliorations.",refresh:"Actualiser",autoOn:"Auto : ON",autoOff:"Auto : OFF",rulesTitle:"Rรจgles du commerce",rulesHint:"Ces rรจgles entraรฎnent le feu tricolore.",saveRules:"Enregistrer",listen:"๐๏ธ รCOUTER",hi:"๐ ",reportTitle:"Rapport terrain",reportPh:"Que s'est-il passรฉ pendant votre quart ?",sendReport:"Envoyer",fbTitle:"Feedback terrain",fbPh:"Que s'est-il passรฉ ? Que faut-il amรฉliorer ?",sendFeedback:"Envoyer",switchUser:"Changer d'utilisateur",wallHead:"๐ญ Suite J.Franco โ En direct",wallPulse:"Pouls du terrain",noActivity:"(aucune activitรฉ)",start:"โถ DรMARRER",listening:"รcouteโฆ parlez maintenant",listeningHint:"La conversation est captรฉe et rรฉpartie par personne.",stopListening:"โน Arrรชter",summaryTitle:"Rรฉsumรฉ de la conversation",confirm:"Confirmer โ",confirmed:"Confirmรฉ โ",sentNote:"Envoyรฉ en cuisine et au central",newConv:"Nouvelle conversation",ordersTitle:"Commandes โ cuisine et addition",person:"Personne",noSummary:"Le rรฉsumรฉ apparaรฎtra ici au fil de la conversation.",prep:"En prรฉparation",ready:"Prรชt",delivered:"Servi",sent:"Envoyรฉ",back:"Retour",sayPh:"Parlez ou รฉcrivez ce que chaque personne a ditโฆ",sendPhrase:"Envoyer",dictate:"๐๏ธ Dicter",aiHint:"La voix et le texte vont directement ร lโIA โ le rรฉsumรฉ apparaรฎt seul.",micUnsupported:"Dictรฉe non prise en charge",processing:"LโIA rรฉsumeโฆ",sectorTab:"Secteur",sectorPresets:"Secteurs prรฉdรฉfinis",customSector:"Secteur personnalisรฉ",saveSector:"Enregistrer le secteur",sectorSaved:"Secteur enregistrรฉ.",aiSuggest:"Suggรฉrer avec lโIA (copier lโinvite)",aiSectorCopied:"Invite copiรฉe โ collez-la dans DeepSeek Harness.",fillBoth:"Saisissez votre utilisateur et votre mot de passe.",loggingIn:"Connexionโฆ",noOrders:"Aucune commande โ confirmez des รฉlรฉments dans le rรฉsumรฉ.",noUsage:"Aucun usage signalรฉ.",noReports:"Aucun rapport terrain.",lvlEmployee:"Terrain",lvlLead:"Superviseur",lvlOwner:"Propriรฉtaire",labelPh:"Intitulรฉ du rรดle (ex. Cuisinier)",newOrder:"NOUVELLE COMMANDE",enableNotif:"๐ Activer les notifications",notifHint:"La tablette de cuisine sonne et clignote ร l'arrivรฉe d'une commande."},
|
|
231
|
+
de:{login:"Anmelden",user:"Benutzer",password:"Passwort",loginBtn:"Anmelden",loginHint:"Konten verwaltet der Inhaber.",loginFailed:"Anmeldung fehlgeschlagen.",cannotReach:"Server nicht erreichbar. Lรคuft er?",workerAdded:"Mitarbeiter hinzugefรผgt.",saved:"Gespeichert.",reportSent:"Bericht gesendet.",feedbackSent:"Feedback gesendet.",wallOpen:"Live-Anzeige",logout:"Abmelden",overview:"รbersicht",field:"Feld",rules:"Regeln",reports:"Berichte",week:"Diese Woche",feedback:"Feedback",workersActive:"Aktive Mitarbeiter",reportsTotal:"Berichte gesamt",workers:"Mitarbeiter",thUser:"Benutzer",thRole:"Rolle",addWorker:"Mitarbeiter hinzufรผgen",userName:"Benutzername",addBtn:"Hinzufรผgen",usage:"Nutzung & Kosten",usageSub:"(pro Mitarbeiter, geschรคtzt)",thWorker:"Mitarbeiter",thSessions:"Sitzungen",thTokens:"Tokens",thCost:"Kosten ca.",panel:"Aktionspanel",panelNote:"Mitarbeiter รถffnen das Panel auf Tablet oder Handy.",openPanel:"Panel รถffnen",fieldReports:"Feldberichte",feedbackQueue:"Feedback-Warteschlange",feedbackHint:"Der Agent liest diese Warteschlange und behebt Fehler.",refresh:"Aktualisieren",autoOn:"Auto: AN",autoOff:"Auto: AUS",rulesTitle:"Geschรคftsregeln",rulesHint:"Diese Regeln trainieren die Ampel.",saveRules:"Regeln speichern",listen:"๐๏ธ ZUHรREN",hi:"๐ ",reportTitle:"Feldbericht",reportPh:"Was ist in Ihrer Schicht passiert?",sendReport:"Senden",fbTitle:"Feld-Feedback",fbPh:"Was ist passiert? Was soll besser werden?",sendFeedback:"Senden",switchUser:"Benutzer wechseln",wallHead:"๐ญ J.Franco-Suite โ Live",wallPulse:"Puls im Feld",noActivity:"(noch keine Aktivitรคt)",start:"โถ STARTEN",listening:"Hรถre zuโฆ sprich jetzt",listeningHint:"Das Gesprรคch wird erfasst und pro Person aufgeteilt.",stopListening:"โน Stopp",summaryTitle:"Gesprรคchsรผbersicht",confirm:"Bestรคtigen โ",confirmed:"Bestรคtigt โ",sentNote:"An Kรผche & Zentrale gesendet",newConv:"Neues Gesprรคch",ordersTitle:"Bestellungen โ Kรผche & Rechnung",person:"Person",noSummary:"Die รbersicht erscheint hier, sobald das Gesprรคch erkannt wird.",prep:"In Zubereitung",ready:"Fertig",delivered:"Serviert",sent:"Gesendet",back:"Zurรผck",sayPh:"Sprechen oder tippen Sie, was jede Person gesagt hatโฆ",sendPhrase:"Senden",dictate:"๐๏ธ Diktieren",aiHint:"Sprache und Text gehen direkt an die KI โ die รbersicht erscheint automatisch.",micUnsupported:"Diktat nicht unterstรผtzt",processing:"Die KI fasst zusammenโฆ",sectorTab:"Branche",sectorPresets:"Branchen-Vorlagen",customSector:"Eigene Branche",saveSector:"Branche speichern",sectorSaved:"Branche gespeichert.",aiSuggest:"Mit KI vorschlagen (Prompt kopieren)",aiSectorCopied:"KI-Prompt kopiert โ in DeepSeek Harness einfรผgen.",fillBoth:"Benutzer und Passwort eingeben.",loggingIn:"Anmeldungโฆ",noOrders:"Noch keine Bestellungen โ Elemente in der รbersicht bestรคtigen.",noUsage:"Noch keine Nutzung gemeldet.",noReports:"Noch keine Feldberichte.",lvlEmployee:"Feld",lvlLead:"Aufsicht",lvlOwner:"Inhaber",labelPh:"Rollenname (z. B. Koch)",newOrder:"NEUE BESTELLUNG",enableNotif:"๐ Benachrichtigungen aktivieren",notifHint:"Das Kรผchen-Tablet piept und blinkt bei neuer Bestellung."},
|
|
232
|
+
it:{login:"Accedi",user:"Utente",password:"Password",loginBtn:"Accedi",loginHint:"Gli account li gestisce il proprietario.",loginFailed:"Accesso fallito.",cannotReach:"Server non raggiungibile. ร in esecuzione?",workerAdded:"Lavoratore aggiunto.",saved:"Salvato.",reportSent:"Report inviato.",feedbackSent:"Feedback inviato.",wallOpen:"Schermo live",logout:"Esci",overview:"Panoramica",field:"Campo",rules:"Regole",reports:"Report",week:"Questa settimana",feedback:"Feedback",workersActive:"Lavoratori attivi",reportsTotal:"Report totali",workers:"Lavoratori",thUser:"Utente",thRole:"Ruolo",addWorker:"Aggiungi lavoratore",userName:"Nome utente",addBtn:"Aggiungi",usage:"Uso e costi",usageSub:"(per lavoratore, stimato)",thWorker:"Lavoratore",thSessions:"Sessioni",thTokens:"Token",thCost:"Costo stim.",panel:"Pannello Azioni",panelNote:"I lavoratori aprono il pannello da tablet o telefono.",openPanel:"Apri il pannello",fieldReports:"Report di campo",feedbackQueue:"Coda feedback",feedbackHint:"L'agente legge questa coda e risolve errori e migliorie.",refresh:"Aggiorna",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regole del negozio",rulesHint:"Queste regole addestrano il semaforo.",saveRules:"Salva regole",listen:"๐๏ธ ASCOLTA",hi:"๐ ",reportTitle:"Report di campo",reportPh:"Cosa รจ successo nel tuo turno?",sendReport:"Invia",fbTitle:"Feedback di campo",fbPh:"Cosa รจ successo? Cosa va migliorato?",sendFeedback:"Invia",switchUser:"Cambia utente",wallHead:"๐ญ Suite J.Franco โ Live",wallPulse:"Battito del campo",noActivity:"(nessuna attivitร )",start:"โถ INIZIA",listening:"In ascoltoโฆ parla ora",listeningHint:"La conversazione viene catturata e divisa per persona.",stopListening:"โน Ferma",summaryTitle:"Riepilogo conversazione",confirm:"Conferma โ",confirmed:"Confermato โ",sentNote:"Inviato a cucina e centrale",newConv:"Nuova conversazione",ordersTitle:"Ordini โ cucina e conto",person:"Persona",noSummary:"Il riepilogo apparirร qui man mano che la conversazione viene rilevata.",prep:"In preparazione",ready:"Pronto",delivered:"Servito",sent:"Inviato",back:"Indietro",sayPh:"Parla o scrivi cosa ha detto ogni personaโฆ",sendPhrase:"Invia",dictate:"๐๏ธ Detta",aiHint:"Voce e testo vanno direttamente allโIA โ il riepilogo appare da solo.",micUnsupported:"Dettatura non supportata",processing:"LโIA sta riassumendoโฆ",sectorTab:"Settore",sectorPresets:"Settori predefiniti",customSector:"Settore personalizzato",saveSector:"Salva settore",sectorSaved:"Settore salvato.",aiSuggest:"Suggerisci con lโIA (copia prompt)",aiSectorCopied:"Prompt copiato โ incollalo in DeepSeek Harness.",fillBoth:"Inserisci utente e password.",loggingIn:"Accessoโฆ",noOrders:"Ancora nessun ordine โ conferma elementi nel riepilogo.",noUsage:"Nessun utilizzo segnalato.",noReports:"Nessun report di campo.",lvlEmployee:"Terreno",lvlLead:"Supervisore",lvlOwner:"Proprietario",labelPh:"Etichetta ruolo (es. Cuoco)",newOrder:"NUOVO ORDINE",enableNotif:"๐ Attiva notifiche",notifHint:"Il tablet di cucina suona e lampeggia all'arrivo di un ordine."},
|
|
233
|
+
pt:{login:"Entrar",user:"Usuรกrio",password:"Senha",loginBtn:"Entrar",loginHint:"As contas sรฃo geridas pelo dono.",loginFailed:"Falha no login.",cannotReach:"Servidor inacessรญvel. Estรก a correr?",workerAdded:"Trabalhador adicionado.",saved:"Guardado.",reportSent:"Relatรณrio enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Painel ao vivo",logout:"Sair",overview:"Visรฃo geral",field:"Campo",rules:"Regras",reports:"Relatรณrios",week:"Esta semana",feedback:"Feedback",workersActive:"Trabalhadores ativos",reportsTotal:"Total de relatรณrios",workers:"Trabalhadores",thUser:"Usuรกrio",thRole:"Funรงรฃo",addWorker:"Adicionar trabalhador",userName:"Nome de usuรกrio",addBtn:"Adicionar",usage:"Uso e custo",usageSub:"(por trabalhador, estimado)",thWorker:"Trabalhador",thSessions:"Sessรตes",thTokens:"Tokens",thCost:"Custo est.",panel:"Painel de Aรงรฃo",panelNote:"Os trabalhadores abrem o painel no tablet ou telemรณvel.",openPanel:"Abrir painel",fieldReports:"Relatรณrios de campo",feedbackQueue:"Fila de feedback",feedbackHint:"O agente lรช esta fila e resolve erros e melhorias.",refresh:"Atualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regras do negรณcio",rulesHint:"Estas regras treinam o semรกforo.",saveRules:"Guardar regras",listen:"๐๏ธ OUVIR",hi:"๐ ",reportTitle:"Relatรณrio de campo",reportPh:"O que aconteceu no seu turno?",sendReport:"Enviar",fbTitle:"Feedback de campo",fbPh:"O que aconteceu? O que deve melhorar?",sendFeedback:"Enviar",switchUser:"Trocar de usuรกrio",wallHead:"๐ญ Suite J.Franco โ Ao vivo",wallPulse:"Pulso do campo",noActivity:"(sem atividade)",start:"โถ INICIAR",listening:"A ouvirโฆ fale agora",listeningHint:"A conversa รฉ captada e dividida por pessoa.",stopListening:"โน Parar",summaryTitle:"Resumo da conversa",confirm:"Confirmar โ",confirmed:"Confirmado โ",sentNote:"Enviado para cozinha e central",newConv:"Nova conversa",ordersTitle:"Pedidos โ cozinha e conta",person:"Pessoa",noSummary:"O resumo aparece aqui conforme a conversa รฉ detetada.",prep:"A preparar",ready:"Pronto",delivered:"Entregue",sent:"Enviado",back:"Voltar",sayPh:"Fale ou escreva o que cada pessoa disseโฆ",sendPhrase:"Enviar",dictate:"๐๏ธ Ditar",aiHint:"Voz e texto vรฃo direto ร IA โ o resumo aparece sozinho.",micUnsupported:"Ditado nรฃo suportado",processing:"A IA estรก a resumirโฆ",sectorTab:"Setor",sectorPresets:"Setores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar setor",sectorSaved:"Setor guardado.",aiSuggest:"Sugerir com IA (copiar prompt)",aiSectorCopied:"Prompt copiado โ cole no DeepSeek Harness.",fillBoth:"Digite usuรกrio e senha.",loggingIn:"A entrarโฆ",noOrders:"Ainda sem pedidos โ confirme itens no resumo.",noUsage:"Ainda sem uso reportado.",noReports:"Ainda sem relatรณrios de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dono",labelPh:"Funรงรฃo (ex. Cozinheiro)",newOrder:"NOVO PEDIDO",enableNotif:"๐ Ativar notificaรงรตes",notifHint:"O tablet da cozinha apita e pisca quando chega um pedido."},
|
|
234
|
+
zh:{login:"็ปๅฝ",user:"็จๆท",password:"ๅฏ็ ",loginBtn:"็ปๅฝ",loginHint:"่ดฆๆท็ฑไผไธไธป็ฎก็ใ",loginFailed:"็ปๅฝๅคฑ่ดฅใ",cannotReach:"ๆ ๆณ่ฟๆฅๆๅกๅจใๅฎๆฏๅฆๅจ่ฟ่ก๏ผ",workerAdded:"ๅๅทฅๅทฒๆทปๅ ใ",saved:"ๅทฒไฟๅญใ",reportSent:"ๆฅๅๅทฒๅ้ใ",feedbackSent:"ๅ้ฆๅทฒๅ้ใ",wallOpen:"ๅฎๆถ็ๆฟ",logout:"้ๅบ",overview:"ๆป่ง",field:"็ฐๅบ",rules:"่งๅ",reports:"ๆฅๅ",week:"ๆฌๅจ",feedback:"ๅ้ฆ",workersActive:"ๆดป่ทๅๅทฅ",reportsTotal:"ๆฅๅๆปๆฐ",workers:"ๅๅทฅ",thUser:"็จๆท",thRole:"่ง่ฒ",addWorker:"ๆทปๅ ๅๅทฅ",userName:"็จๆทๅ",addBtn:"ๆทปๅ ",usage:"็จ้ไธๆๆฌ",usageSub:"๏ผๆฏไฝๅๅทฅ๏ผไผฐ็ฎ๏ผ",thWorker:"ๅๅทฅ",thSessions:"ไผ่ฏ",thTokens:"Token",thCost:"้ขไผฐๆๆฌ",panel:"ๆไฝ้ขๆฟ",panelNote:"ๅๅทฅๅจๅนณๆฟๆๆๆบไธๆๅผ้ขๆฟใ",openPanel:"ๆๅผ้ขๆฟ",fieldReports:"็ฐๅบๆฅๅ",feedbackQueue:"ๅ้ฆ้ๅ",feedbackHint:"ๆบ่ฝไฝ่ฏปๅๆญค้ๅๅนถ่งฃๅณ้ฎ้ขใ",refresh:"ๅทๆฐ",autoOn:"่ชๅจ๏ผๅผ",autoOff:"่ชๅจ๏ผๅ
ณ",rulesTitle:"ไธๅก่งๅ",rulesHint:"่ฟไบ่งๅ่ฎญ็ป็บข็ปฟ็ฏใ",saveRules:"ไฟๅญ่งๅ",listen:"๐๏ธ ่ๅฌ",hi:"๐ ",reportTitle:"็ฐๅบๆฅๅ",reportPh:"ไฝ ็็ญๆฌกๅ็ไบไปไน๏ผ",sendReport:"ๅ้",fbTitle:"็ฐๅบๅ้ฆ",fbPh:"ๅ็ไบไปไน๏ผไปไน้่ฆๆน่ฟ๏ผ",sendFeedback:"ๅ้",switchUser:"ๅๆข็จๆท",wallHead:"๐ญ J.Franco ๅฅไปถ โ ๅฎๆถ",wallPulse:"็ฐๅบ่ๆ",noActivity:"๏ผๆๆ ็ฐๅบๆดปๅจ๏ผ",start:"โถ ๅผๅง",listening:"ๆญฃๅจ่ๅฌโฆ่ฏท่ฏด่ฏ",listeningHint:"ๅฏน่ฏๆญฃๅจ่ขซๆๆๅนถๆไบบๅๅๅใ",stopListening:"โน ๅๆญข",summaryTitle:"ๅฏน่ฏๆ่ฆ",confirm:"็กฎ่ฎค โ",confirmed:"ๅทฒ็กฎ่ฎค โ",sentNote:"ๅทฒๅ้่ณๅจๆฟไธไธญๅคฎ็ณป็ป",newConv:"ๆฐๅฏน่ฏ",ordersTitle:"่ฎขๅ โ ๅจๆฟไธ่ดฆๅ",person:"ไบบๅ",noSummary:"้็ๅฏน่ฏ่ขซ่ฏๅซ๏ผๆ่ฆๅฐๆพ็คบๅจ่ฟ้ใ",prep:"ๅถไฝไธญ",ready:"ๅฎๆ",delivered:"ๅทฒ้่พพ",sent:"ๅทฒๅ้",back:"่ฟๅ",sayPh:"่ฏดๅบๆ่พๅ
ฅๆฏไธชไบบ่ฏด็่ฏโฆโฆ",sendPhrase:"ๅ้",dictate:"๐๏ธ ๅฌๅ",aiHint:"่ฏญ้ณๅๆๅญ็ด่พพ AI โ ๆ่ฆ่ชๅจๅบ็ฐใ",micUnsupported:"ๆญคๆต่งๅจไธๆฏๆๅฌๅ",processing:"AI ๆญฃๅจๆป็ปโฆโฆ",sectorTab:"่กไธ",sectorPresets:"้ข่ฎพ่กไธ",customSector:"่ชๅฎไน่กไธ",saveSector:"ไฟๅญ่กไธ",sectorSaved:"่กไธๅทฒไฟๅญใ",aiSuggest:"็จ AI ๅปบ่ฎฎ๏ผๅคๅถๆ็คบ๏ผ",aiSectorCopied:"AI ๆ็คบๅทฒๅคๅถ โ ็ฒ่ดดๅฐ DeepSeek Harnessใ",fillBoth:"่ฏท่พๅ
ฅ็จๆทๅๅๅฏ็ ใ",loggingIn:"็ปๅฝไธญโฆโฆ",noOrders:"ๆๆ ่ฎขๅ โ ่ฏทๅจๆ่ฆไธญ็กฎ่ฎค้กน็ฎใ",noUsage:"ๆๆ ็จ้ๆฅๅใ",noReports:"ๆๆ ็ฐๅบๆฅๅใ",lvlEmployee:"็ฐๅบ",lvlLead:"ไธป็ฎก",lvlOwner:"ไธไธป",labelPh:"่ง่ฒๆ ็ญพ๏ผๅฆ๏ผๅจๅธ๏ผ",newOrder:"ๆฐ่ฎขๅ",enableNotif:"๐ ๅผๅฏ้็ฅ",notifHint:"ๆฐ่ฎขๅๅฐ่พพๆถๅจๆฟๅนณๆฟไผๅ้ๅนถ้ช็ใ"},
|
|
235
|
+
ja:{login:"ใญใฐใคใณ",user:"ใฆใผใถใผ",password:"ใในใฏใผใ",loginBtn:"ใญใฐใคใณ",loginHint:"ใขใซใฆใณใใฏไบๆฅญไธปใ็ฎก็ใใพใใ",loginFailed:"ใญใฐใคใณๅคฑๆใ",cannotReach:"ใตใผใใผใซๆฅ็ถใงใใพใใใ่ตทๅใใฆใใพใใ๏ผ",workerAdded:"ๅพๆฅญๅกใ่ฟฝๅ ใใพใใใ",saved:"ไฟๅญใใพใใใ",reportSent:"ๅ ฑๅใ้ไฟกใใพใใใ",feedbackSent:"ใใฃใผใใใใฏใ้ไฟกใใพใใใ",wallOpen:"ใฉใคใๆฒ็คบๆฟ",logout:"ใญใฐใขใฆใ",overview:"ๆฆ่ฆ",field:"็พๅ ด",rules:"ใซใผใซ",reports:"ๅ ฑๅ",week:"ไป้ฑ",feedback:"ใใฃใผใใใใฏ",workersActive:"็จผๅไธญใฎๅพๆฅญๅก",reportsTotal:"ๅ ฑๅ็ทๆฐ",workers:"ๅพๆฅญๅก",thUser:"ใฆใผใถใผ",thRole:"ๅฝนๅฒ",addWorker:"ๅพๆฅญๅกใ่ฟฝๅ ",userName:"ใฆใผใถใผๅ",addBtn:"่ฟฝๅ ",usage:"ๅฉ็จ้ใจใณในใ",usageSub:"๏ผๅพๆฅญๅกใใจใๆจๅฎ๏ผ",thWorker:"ๅพๆฅญๅก",thSessions:"ใปใใทใงใณ",thTokens:"ใใผใฏใณ",thCost:"ๆจๅฎใณในใ",panel:"ใขใฏใทใงใณใใใซ",panelNote:"ๅพๆฅญๅกใฏใฟใใฌใใใในใใใงใใใซใ้ใใพใใ",openPanel:"ใใใซใ้ใ",fieldReports:"็พๅ ดๅ ฑๅ",feedbackQueue:"ใใฃใผใใใใฏๅพ
ใก่กๅ",feedbackHint:"ใจใผใธใงใณใใใใฎ่กๅใ่ชญใฟใๅ้กใ่งฃๆฑบใใพใใ",refresh:"ๆดๆฐ",autoOn:"่ชๅ: ON",autoOff:"่ชๅ: OFF",rulesTitle:"ๆฅญๅใซใผใซ",rulesHint:"ใใใใฎใซใผใซใไฟกๅทใ่จ็ทดใใพใใ",saveRules:"ใซใผใซใไฟๅญ",listen:"๐๏ธ ่ใ",hi:"๐ ",reportTitle:"็พๅ ดๅ ฑๅ",reportPh:"ใทใใใงไฝใใใใพใใใ๏ผ",sendReport:"้ไฟก",fbTitle:"็พๅ ดใใฃใผใใใใฏ",fbPh:"ไฝใ่ตทใใพใใใ๏ผไฝใๆนๅใในใ๏ผ",sendFeedback:"้ไฟก",switchUser:"ใฆใผใถใผๅๆฟ",wallHead:"๐ญ J.Franco ในใคใผใ โ ใฉใคใ",wallPulse:"็พๅ ดใฎ้ผๅ",noActivity:"๏ผใพใ ็พๅ ดๆดปๅใชใ๏ผ",start:"โถ ้ๅง",listening:"่ใใฆใใพใโฆใฉใใ",listeningHint:"ไผ่ฉฑใๆๆใใไบบ็ฉใใจใซๅใใฆใใพใใ",stopListening:"โน ๅๆญข",summaryTitle:"ไผ่ฉฑใฎใพใจใ",confirm:"็ขบ่ช โ",confirmed:"็ขบ่ชๆธใฟ โ",sentNote:"ๅจๆฟใจไธญๅคฎใธ้ไฟกๆธใฟ",newConv:"ๆฐใใไผ่ฉฑ",ordersTitle:"ๆณจๆ โ ๅจๆฟใจไผ่จ",person:"ไบบ",noSummary:"ไผ่ฉฑใๆคๅบใใใใจใใใซใพใจใใ่กจ็คบใใใพใใ",prep:"่ชฟ็ไธญ",ready:"ๅฎๆ",delivered:"ๆไพๆธใฟ",sent:"้ไฟกๆธใฟ",back:"ๆปใ",sayPh:"ๅไบบใ่ฉฑใใๅ
ๅฎนใ่ฉฑใใๅ
ฅๅโฆ",sendPhrase:"้ไฟก",dictate:"๐๏ธ ้ณๅฃฐๅ
ฅๅ",aiHint:"้ณๅฃฐใจใใญในใใฏ็ดๆฅAIใธ โ ใพใจใใฏ่ชๅใง่กจ็คบใใใพใใ",micUnsupported:"้ณๅฃฐๅ
ฅๅ้ๅฏพๅฟ",processing:"AIใ่ฆ็ดไธญโฆ",sectorTab:"ใปใฏใฟใผ",sectorPresets:"ใปใฏใฟใผใใชใปใใ",customSector:"ใซในใฟใ ใปใฏใฟใผ",saveSector:"ใปใฏใฟใผใไฟๅญ",sectorSaved:"ใปใฏใฟใผใไฟๅญใใพใใใ",aiSuggest:"AIใงๆๆก๏ผใใญใณใใใใณใใผ๏ผ",aiSectorCopied:"AIใใญใณใใใใณใใผใใพใใ โ DeepSeek Harnessใซ่ฒผใไปใใ",fillBoth:"ใฆใผใถใผใจใในใฏใผใใๅ
ฅๅใใฆใใ ใใใ",loggingIn:"ใญใฐใคใณไธญโฆ",noOrders:"ใพใ ๆณจๆใใใใพใใ โ ใพใจใใง้
็ฎใ็ขบ่ชใใฆใใ ใใใ",noUsage:"ใพใ ๅฉ็จๅ ฑๅใใใใพใใใ",noReports:"ใพใ ็พๅ ดๅ ฑๅใใใใพใใใ",lvlEmployee:"็พๅ ด",lvlLead:"็ฃ็ฃ",lvlOwner:"ใชใผใใผ",labelPh:"ๅฝนๅฒๅ๏ผไพ๏ผ่ชฟ็ๅธซ๏ผ",newOrder:"ๆฐ่ฆๆณจๆ",enableNotif:"๐ ้็ฅใๆๅนๅ",notifHint:"ๆณจๆใๅฑใใจๅจๆฟใฟใใฌใใใ้ณใจ็นๆป
ใง็ฅใใใพใใ"},
|
|
236
|
+
ko:{login:"๋ก๊ทธ์ธ",user:"์ฌ์ฉ์",password:"๋น๋ฐ๋ฒํธ",loginBtn:"๋ก๊ทธ์ธ",loginHint:"๊ณ์ ์ ์ฌ์
์ฃผ๊ฐ ๊ด๋ฆฌํฉ๋๋ค.",loginFailed:"๋ก๊ทธ์ธ ์คํจ.",cannotReach:"์๋ฒ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. ์คํ ์ค์ธ๊ฐ์?",workerAdded:"์ง์์ด ์ถ๊ฐ๋์์ต๋๋ค.",saved:"์ ์ฅ๋์์ต๋๋ค.",reportSent:"๋ณด๊ณ ์๋ฅผ ๋ณด๋์ต๋๋ค.",feedbackSent:"ํผ๋๋ฐฑ์ ๋ณด๋์ต๋๋ค.",wallOpen:"๋ผ์ด๋ธ ๋ณด๋",logout:"๋ก๊ทธ์์",overview:"๊ฐ์",field:"ํ์ฅ",rules:"๊ท์น",reports:"๋ณด๊ณ ์",week:"์ด๋ฒ ์ฃผ",feedback:"ํผ๋๋ฐฑ",workersActive:"ํ์ฑ ์ง์",reportsTotal:"์ด ๋ณด๊ณ ์",workers:"์ง์",thUser:"์ฌ์ฉ์",thRole:"์ญํ ",addWorker:"์ง์ ์ถ๊ฐ",userName:"์ฌ์ฉ์ ์ด๋ฆ",addBtn:"์ถ๊ฐ",usage:"์ฌ์ฉ๋ ๋ฐ ๋น์ฉ",usageSub:"(์ง์๋ณ, ์ถ์ )",thWorker:"์ง์",thSessions:"์ธ์
",thTokens:"ํ ํฐ",thCost:"์ถ์ ๋น์ฉ",panel:"์ก์
ํจ๋",panelNote:"์ง์์ ํ๋ธ๋ฆฟ์ด๋ ํด๋ํฐ์์ ํจ๋์ ์ฝ๋๋ค.",openPanel:"ํจ๋ ์ด๊ธฐ",fieldReports:"ํ์ฅ ๋ณด๊ณ ์",feedbackQueue:"ํผ๋๋ฐฑ ๋๊ธฐ์ด",feedbackHint:"์์ด์ ํธ๊ฐ ์ด ๋๊ธฐ์ด์ ์ฝ๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.",refresh:"์๋ก๊ณ ์นจ",autoOn:"์๋: ON",autoOff:"์๋: OFF",rulesTitle:"์ฌ์
๊ท์น",rulesHint:"์ด ๊ท์น์ด ์ ํธ๋ฑ์ ํ๋ จํฉ๋๋ค.",saveRules:"๊ท์น ์ ์ฅ",listen:"๐๏ธ ๋ฃ๊ธฐ",hi:"๐ ",reportTitle:"ํ์ฅ ๋ณด๊ณ ์",reportPh:"๊ทผ๋ฌด ์ค ๋ฌด์จ ์ผ์ด ์์๋์?",sendReport:"๋ณด๋ด๊ธฐ",fbTitle:"ํ์ฅ ํผ๋๋ฐฑ",fbPh:"๋ฌด์จ ์ผ์ด ์์๋์? ๋ฌด์์ ๊ฐ์ ํ ๊น์?",sendFeedback:"๋ณด๋ด๊ธฐ",switchUser:"์ฌ์ฉ์ ์ ํ",wallHead:"๐ญ J.Franco ์ค์ํธ โ ๋ผ์ด๋ธ",wallPulse:"ํ์ฅ์ ๋งฅ๋ฐ",noActivity:"(ํ์ฅ ํ๋ ์์)",start:"โถ ์์",listening:"๋ฃ๋ ์คโฆ ๋ง์ํ์ธ์",listeningHint:"๋ํ๋ฅผ ํฌ์ฐฉํ์ฌ ์ฌ๋๋ณ๋ก ๋๋๊ณ ์์ต๋๋ค.",stopListening:"โน ์ค์ง",summaryTitle:"๋ํ ์์ฝ",confirm:"ํ์ธ โ",confirmed:"ํ์ธ๋จ โ",sentNote:"์ฃผ๋ฐฉ ๋ฐ ์ค์์ผ๋ก ์ ์ก๋จ",newConv:"์ ๋ํ",ordersTitle:"์ฃผ๋ฌธ โ ์ฃผ๋ฐฉ ๋ฐ ๊ณ์ฐ",person:"์ฌ๋",noSummary:"๋ํ๊ฐ ๊ฐ์ง๋๋ฉด ์์ฝ์ด ์ฌ๊ธฐ์ ํ์๋ฉ๋๋ค.",prep:"์กฐ๋ฆฌ ์ค",ready:"์๋ฃ",delivered:"์๋น๋จ",sent:"์ ์ก๋จ",back:"๋ค๋ก",sayPh:"๊ฐ ์ฌ๋์ด ๋งํ ๋ด์ฉ์ ๋งํ๊ฑฐ๋ ์
๋ ฅโฆ",sendPhrase:"๋ณด๋ด๊ธฐ",dictate:"๐๏ธ ๋ฐ์์ฐ๊ธฐ",aiHint:"์์ฑ๊ณผ ํ
์คํธ๊ฐ AI๋ก ๋ฐ๋ก ์ ๋ฌ โ ์์ฝ์ด ์๋ ํ์๋ฉ๋๋ค.",micUnsupported:"๋ฐ์์ฐ๊ธฐ ๋ฏธ์ง์",processing:"AI๊ฐ ์์ฝ ์คโฆ",sectorTab:"์
์ข
",sectorPresets:"์
์ข
ํ๋ฆฌ์
",customSector:"์ฌ์ฉ์ ์ ์ ์
์ข
",saveSector:"์
์ข
์ ์ฅ",sectorSaved:"์
์ข
์ด ์ ์ฅ๋์์ต๋๋ค.",aiSuggest:"AI๋ก ์ ์(ํ๋กฌํํธ ๋ณต์ฌ)",aiSectorCopied:"AI ํ๋กฌํํธ ๋ณต์ฌ๋จ โ DeepSeek Harness์ ๋ถ์ฌ๋ฃ๊ธฐ.",fillBoth:"์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์.",loggingIn:"๋ก๊ทธ์ธ ์คโฆ",noOrders:"์์ง ์ฃผ๋ฌธ์ด ์์ต๋๋ค โ ์์ฝ์์ ํญ๋ชฉ์ ํ์ธํ์ธ์.",noUsage:"์์ง ์ฌ์ฉ ๋ณด๊ณ ๊ฐ ์์ต๋๋ค.",noReports:"์์ง ํ์ฅ ๋ณด๊ณ ์๊ฐ ์์ต๋๋ค.",lvlEmployee:"ํ์ฅ",lvlLead:"๊ฐ๋
",lvlOwner:"์์ ์ฃผ",labelPh:"์ญํ ์ด๋ฆ(์: ์๋ฆฌ์ฌ)",newOrder:"์ ์ฃผ๋ฌธ",enableNotif:"๐ ์๋ฆผ ํ์ฑํ",notifHint:"์ฃผ๋ฌธ์ด ๋์ฐฉํ๋ฉด ์ฃผ๋ฐฉ ํ๋ธ๋ฆฟ์ด ์๋ฆฌ์ ํจ๊ป ๊น๋ฐ์
๋๋ค."},
|
|
237
|
+
ar:{login:"ุชุณุฌูู ุงูุฏุฎูู",user:"ุงูู
ุณุชุฎุฏู
",password:"ููู
ุฉ ุงูู
ุฑูุฑ",loginBtn:"ุฏุฎูู",loginHint:"ุงูุญุณุงุจุงุช ูุฏูุฑูุง ุตุงุญุจ ุงูุนู
ู.",loginFailed:"ูุดู ุชุณุฌูู ุงูุฏุฎูู.",cannotReach:"ุชุนุฐุฑ ุงููุตูู ุฅูู ุงูุฎุงุฏู
. ูู ูู ููุฏ ุงูุชุดุบููุ",workerAdded:"ุชู
ุช ุฅุถุงูุฉ ุงูู
ูุธู.",saved:"ุชู
ุงูุญูุธ.",reportSent:"ุชู
ุฅุฑุณุงู ุงูุชูุฑูุฑ.",feedbackSent:"ุชู
ุฅุฑุณุงู ุงูู
ูุงุญุธุงุช.",wallOpen:"ุงูููุญุฉ ุงูู
ุจุงุดุฑุฉ",logout:"ุฎุฑูุฌ",overview:"ูุธุฑุฉ ุนุงู
ุฉ",field:"ุงูู
ูุฏุงู",rules:"ุงูููุงุนุฏ",reports:"ุงูุชูุงุฑูุฑ",week:"ูุฐุง ุงูุฃุณุจูุน",feedback:"ุงูู
ูุงุญุธุงุช",workersActive:"ู
ูุธููู ูุดุทูู",reportsTotal:"ุฅุฌู
ุงูู ุงูุชูุงุฑูุฑ",workers:"ุงูู
ูุธููู",thUser:"ุงูู
ุณุชุฎุฏู
",thRole:"ุงูุฏูุฑ",addWorker:"ุฅุถุงูุฉ ู
ูุธู",userName:"ุงุณู
ุงูู
ุณุชุฎุฏู
",addBtn:"ุฅุถุงูุฉ",usage:"ุงูุงุณุชุฎุฏุงู
ูุงูุชูููุฉ",usageSub:"(ููู ู
ูุธูุ ุชูุฏูุฑู)",thWorker:"ุงูู
ูุธู",thSessions:"ุงูุฌูุณุงุช",thTokens:"ุงูุฑู
ูุฒ",thCost:"ุงูุชูููุฉ ุงูุชูุฏูุฑูุฉ",panel:"ููุญุฉ ุงูุฅุฌุฑุงุกุงุช",panelNote:"ููุชุญ ุงูู
ูุธููู ุงูููุญุฉ ู
ู ุฃุฌูุฒุชูู
.",openPanel:"ูุชุญ ุงูููุญุฉ",fieldReports:"ุชูุงุฑูุฑ ุงูู
ูุฏุงู",feedbackQueue:"ูุงุฆู
ุฉ ุงูู
ูุงุญุธุงุช",feedbackHint:"ููุฑุฃ ุงููููู ูุฐู ุงููุงุฆู
ุฉ ููุญู ุงูู
ุดููุงุช.",refresh:"ุชุญุฏูุซ",autoOn:"ุชููุงุฆู: ON",autoOff:"ุชููุงุฆู: OFF",rulesTitle:"ููุงุนุฏ ุงูุนู
ู",rulesHint:"ูุฐู ุงูููุงุนุฏ ุชุฏุฑูุจ ุงูุฅุดุงุฑุฉ ุงูุถูุฆูุฉ.",saveRules:"ุญูุธ ุงูููุงุนุฏ",listen:"๐๏ธ ุงุณุชู
ุน",hi:"๐ ",reportTitle:"ุชูุฑูุฑ ู
ูุฏุงูู",reportPh:"ู
ุงุฐุง ุญุฏุซ ูู ููุจุชูุ",sendReport:"ุฅุฑุณุงู",fbTitle:"ู
ูุงุญุธุงุช ู
ูุฏุงููุฉ",fbPh:"ู
ุงุฐุง ุญุฏุซุ ู
ุง ุงูุฐู ูุฌุจ ุชุญุณูููุ",sendFeedback:"ุฅุฑุณุงู",switchUser:"ุชุจุฏูู ุงูู
ุณุชุฎุฏู
",wallHead:"๐ญ ู
ุฌู
ูุนุฉ J.Franco โ ู
ุจุงุดุฑ",wallPulse:"ูุจุถ ุงูู
ูุฏุงู",noActivity:"(ูุง ูุดุงุท ุจุนุฏ)",start:"โถ ุงุจุฏุฃ",listening:"ุฃุณุชู
ุนโฆ ุชูุถู ุจุงูุญุฏูุซ",listeningHint:"ูุชู
ุงูุชูุงุท ุงูู
ุญุงุฏุซุฉ ูุชูุณูู
ูุง ุญุณุจ ุงูุฃุดุฎุงุต.",stopListening:"โน ุฅููุงู",summaryTitle:"ู
ูุฎุต ุงูู
ุญุงุฏุซุฉ",confirm:"ุชุฃููุฏ โ",confirmed:"ู
ุคูุฏ โ",sentNote:"ุฃูุฑุณู ุฅูู ุงูู
ุทุจุฎ ูุงููุธุงู
ุงูู
ุฑูุฒู",newConv:"ู
ุญุงุฏุซุฉ ุฌุฏูุฏุฉ",ordersTitle:"ุงูุทูุจุงุช โ ุงูู
ุทุจุฎ ูุงูุญุณุงุจ",person:"ุดุฎุต",noSummary:"ุณูุธูุฑ ุงูู
ูุฎุต ููุง ู
ุน ุงูุชุดุงู ุงูู
ุญุงุฏุซุฉ.",prep:"ููุฏ ุงูุชุญุถูุฑ",ready:"ุฌุงูุฒ",delivered:"ุชู
ุงูุชุณููู
",sent:"ุฃูุฑุณู",back:"ุฑุฌูุน",sayPh:"ุชุญุฏุซ ุฃู ุงูุชุจ ู
ุง ูุงูู ูู ุดุฎุตโฆ",sendPhrase:"ุฅุฑุณุงู",dictate:"๐๏ธ ุฅู
ูุงุก",aiHint:"ุงูุตูุช ูุงููุต ูุตูุงู ู
ุจุงุดุฑุฉ ุฅูู ุงูุฐูุงุก ุงูุงุตุทูุงุนู โ ูุธูุฑ ุงูู
ูุฎุต ุชููุงุฆููุง.",micUnsupported:"ุงูุฅู
ูุงุก ุบูุฑ ู
ุฏุนูู
",processing:"ุงูุฐูุงุก ุงูุงุตุทูุงุนู ููุฎูุตโฆ",sectorTab:"ุงููุทุงุน",sectorPresets:"ุงููุทุงุนุงุช ุงูู
ุญุฏุฏุฉ ู
ุณุจููุง",customSector:"ูุทุงุน ู
ุฎุตุต",saveSector:"ุญูุธ ุงููุทุงุน",sectorSaved:"ุชู
ุญูุธ ุงููุทุงุน.",aiSuggest:"ุงูุชุฑุญ ุจุงูุฐูุงุก ุงูุงุตุทูุงุนู (ูุณุฎ ุงูู
ูุฌู)",aiSectorCopied:"ุชู
ูุณุฎ ุงูู
ูุฌู โ ุงูุตูู ูู DeepSeek Harness.",fillBoth:"ุฃุฏุฎู ุงูู
ุณุชุฎุฏู
ูููู
ุฉ ุงูู
ุฑูุฑ.",loggingIn:"ุฌุงุฑู ุงูุฏุฎููโฆ",noOrders:"ูุง ุชูุฌุฏ ุทูุจุงุช ุจุนุฏ โ ุฃููุฏ ุงูุนูุงุตุฑ ูู ุงูู
ูุฎุต.",noUsage:"ูุง ููุฌุฏ ุงุณุชุฎุฏุงู
ู
ูุจููุบ ุจุนุฏ.",noReports:"ูุง ุชูุฌุฏ ุชูุงุฑูุฑ ู
ูุฏุงููุฉ ุจุนุฏ.",lvlEmployee:"ุงูู
ูุฏุงู",lvlLead:"ู
ุดุฑู",lvlOwner:"ุงูู
ุงูู",labelPh:"ู
ุณู
ู ุงูุฏูุฑ (ู
ุซุงู: ุทุจุงุฎ)",newOrder:"ุทูุจ ุฌุฏูุฏ",enableNotif:"๐ ุชูุนูู ุงูุฅุดุนุงุฑุงุช",notifHint:"ูุตุฏุฑ ุตูุช ูููู
ุถ ููุญ ุงูู
ุทุจุฎ ุนูุฏ ูุตูู ุทูุจ ุฌุฏูุฏ."}
|
|
238
|
+
};
|
|
239
|
+
function haptic(){try{if(navigator.vibrate)navigator.vibrate(25);}catch(e){}if(soundOn){try{const C=window.AudioContext||window.webkitAudioContext;if(!window.__ac)window.__ac=new C();const c=window.__ac;const o=c.createOscillator(),g=c.createGain();o.frequency.value=880;o.connect(g);g.connect(c.destination);g.gain.setValueAtTime(.12,c.currentTime);g.gain.exponentialRampToValueAtTime(.001,c.currentTime+.12);o.start();o.stop(c.currentTime+.12);}catch(e){}}}
|
|
240
|
+
const $=id=>document.getElementById(id);
|
|
241
|
+
let token=null,me=null,auto=false,cur="en",livePoll=null,PACK=null,recording=false,rec=null,soundOn=true,darkOn=false,kitchenPoll=null,lastOrders=0;
|
|
242
|
+
function t(k){return (S[cur]&&S[cur][k])||S.en[k]||k;}
|
|
243
|
+
function applyToggles(){document.body.classList.toggle("dark",darkOn);$("darkBtn").textContent=darkOn?"โ๏ธ":"๐";$("soundBtn").textContent=soundOn?"๐":"๐";}
|
|
244
|
+
$("darkBtn").onclick=()=>{darkOn=!darkOn;try{localStorage.setItem("dsh-dark",darkOn?"1":"0");}catch(e){}applyToggles();};
|
|
245
|
+
$("soundBtn").onclick=()=>{soundOn=!soundOn;try{localStorage.setItem("dsh-sound",soundOn?"1":"0");}catch(e){}applyToggles();};
|
|
246
|
+
try{darkOn=localStorage.getItem("dsh-dark")==="1";soundOn=localStorage.getItem("dsh-sound")!=="0";}catch(e){}
|
|
247
|
+
applyToggles();
|
|
248
|
+
async function reRenderDynamic(){
|
|
249
|
+
if(!me)return;
|
|
250
|
+
if(me.role==="owner"){loadMetrics($("ownerMetrics"));loadUsers();loadUsage();loadField();renderOrders();renderSuggest();}
|
|
251
|
+
else if(me.role==="lead"){loadMetrics($("leadMetrics"));loadLead();renderOrders();}
|
|
252
|
+
else{$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();}
|
|
253
|
+
if(location.search.indexOf("wall=1")>=0)wallTick();
|
|
254
|
+
}
|
|
255
|
+
async function kitchenWatch(){
|
|
256
|
+
const live=await api("/api/live");
|
|
257
|
+
const n=(live.orders||[]).length;
|
|
258
|
+
if(n>lastOrders&&lastOrders>0){
|
|
259
|
+
const o=live.orders[n-1];
|
|
260
|
+
$("kitchenBanner").textContent="๐ "+t("newOrder")+": "+o.person+" โ "+o.request;
|
|
261
|
+
$("kitchenBanner").classList.remove("hidden");
|
|
262
|
+
haptic();
|
|
263
|
+
try{if("Notification" in window&&Notification.permission==="granted"){new Notification(t("newOrder"),{body:o.person+" โ "+o.request});}}catch(e){}
|
|
264
|
+
setTimeout(()=>$("kitchenBanner").classList.add("hidden"),6000);
|
|
265
|
+
}
|
|
266
|
+
lastOrders=n;
|
|
267
|
+
}
|
|
268
|
+
$("notifBtn").onclick=()=>{
|
|
269
|
+
try{
|
|
270
|
+
if("Notification" in window&&Notification.permission!=="granted"){
|
|
271
|
+
Notification.requestPermission().then(()=>{renderOrders();});
|
|
272
|
+
}
|
|
273
|
+
}catch(e){}
|
|
274
|
+
};
|
|
275
|
+
function panelLinks(){const u=me?encodeURIComponent(me.name):"",r=me?encodeURIComponent(me.role):"",lb=me?encodeURIComponent(me.label||me.name):"";$("openPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);$("leadOpenPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);}
|
|
276
|
+
function applyLang(){
|
|
277
|
+
try{localStorage.setItem("dsh-lang",cur);}catch(e){}
|
|
278
|
+
$("loginTitle").textContent=t("login");$("loginUser").placeholder=t("user");
|
|
279
|
+
["loginUser","loginPass"].forEach(id=>$(id).addEventListener("input",()=>$("loginError").classList.add("hidden")));$("loginPass").placeholder=t("password");
|
|
280
|
+
$("loginBtn").textContent=t("loginBtn");$("loginHint").textContent=t("loginHint");$("openWall").textContent=t("wallOpen");$("logoutBtn").textContent=t("logout");
|
|
281
|
+
$("tabOverview").textContent=t("overview");$("tabField").textContent=t("field");$("tabRules").textContent=t("rules");
|
|
282
|
+
$("workersTitle").textContent=t("workers");$("thUser").textContent=t("thUser");$("thRole").textContent=t("thRole");
|
|
283
|
+
$("addWorkerTitle").textContent=t("addWorker");$("newUser").placeholder=t("userName");$("addUserBtn").textContent=t("addBtn");
|
|
284
|
+
$("ordersTitle").textContent=t("ordersTitle");$("leadOrdersTitle").textContent=t("ordersTitle");$("ordersTitle2").textContent=t("ordersTitle");
|
|
285
|
+
$("usageTitle").textContent=t("usage");$("usageSub").textContent=t("usageSub");
|
|
286
|
+
$("thWorker").textContent=t("thWorker");$("thSessions").textContent=t("thSessions");$("thTokens").textContent=t("thTokens");$("thCost").textContent=t("thCost");
|
|
287
|
+
$("panelTitle").textContent=t("panel");$("panelNote").textContent=t("panelNote");$("openPanel").textContent=t("openPanel");
|
|
288
|
+
$("fieldReportsTitle").textContent=t("fieldReports");$("feedbackTitle").textContent=t("feedbackQueue");$("feedbackHint").textContent=t("feedbackHint");
|
|
289
|
+
$("refreshReports").textContent=t("refresh");if(!auto)$("autoRefresh").textContent=t("autoOff");
|
|
290
|
+
$("rulesTitle").textContent=t("rulesTitle");$("rulesHint").textContent=t("rulesHint");$("saveDecisions").textContent=t("saveRules");
|
|
291
|
+
$("leadReportsTitle").textContent=t("fieldReports");$("leadFeedbackTitle").textContent=t("feedbackQueue");$("leadRefresh").textContent=t("refresh");$("leadOpenPanel").textContent=t("openPanel");
|
|
292
|
+
$("startBtn").textContent=t("start");$("listeningText").textContent=t("listening");$("listeningHint").textContent=t("listeningHint");
|
|
293
|
+
$("stopBtn").textContent=t("stopListening");$("summaryTitle").textContent=t("summaryTitle");$("newConvBtn").textContent=t("newConv");$("toHomeBtn").textContent=t("back");
|
|
294
|
+
$("reportTitle").textContent=t("reportTitle");$("reportText").placeholder=t("reportPh");$("reportBtn").textContent=t("sendReport");
|
|
295
|
+
$("fbTitle").textContent=t("fbTitle");$("empFbText").placeholder=t("fbPh");$("empFbBtn").textContent=t("sendFeedback");$("switchBtn").textContent=t("switchUser");
|
|
296
|
+
$("wallHead").textContent=t("wallHead");$("wallPulseTitle").textContent=t("wallPulse");
|
|
297
|
+
$("notifBtn").textContent=t("enableNotif");$("notifHint").textContent=t("notifHint");
|
|
298
|
+
$("optEmployee").textContent=t("lvlEmployee");$("optLead").textContent=t("lvlLead");$("optOwner").textContent=t("lvlOwner");$("newLabel").placeholder=t("labelPh");
|
|
299
|
+
$("tabSector").textContent=t("sectorTab");$("sectorPresetsTitle").textContent=t("sectorPresets");$("customSectorTitle").textContent=t("customSector");$("saveSectorBtn").textContent=t("saveSector");$("aiSectorBtn").textContent=t("aiSuggest");
|
|
300
|
+
$("trailTitle").textContent=t("conversationTrail");$("trailHint").textContent=t("trailHint");
|
|
301
|
+
$("sayText").placeholder=t("sayPh");$("sayBtn").textContent=t("sendPhrase");$("aiHint").textContent=t("aiHint");if(!recording)$("micBtn").textContent=t("dictate");
|
|
302
|
+
document.querySelectorAll(".pill").forEach(p=>p.classList.toggle("active",p.dataset.l===cur));
|
|
303
|
+
panelLinks();
|
|
304
|
+
reRenderDynamic();
|
|
305
|
+
}
|
|
306
|
+
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);}}
|
|
307
|
+
for(const l of Object.keys(LANG))pill(l);
|
|
308
|
+
try{const saved=localStorage.getItem("dsh-lang");if(saved&&S[saved])cur=saved;}catch(e){}
|
|
309
|
+
applyLang();
|
|
310
|
+
function applyPack(){if(!PACK)return;$("tableInput").placeholder=(PACK.tableLabel&&PACK.tableLabel[cur])||"Table";const ot=(PACK.ordersTarget&&PACK.ordersTarget[cur])||t("ordersTitle");$("ordersTitle").textContent=ot;$("leadOrdersTitle").textContent=ot;$("ordersTitle2").textContent=ot;}
|
|
311
|
+
const api=async(p,body)=>{try{const r=await fetch(p,{method:body?"POST":"GET",headers:{"Content-Type":"application/json",...(token?{Authorization:"Bearer "+token}:{})},body:body?JSON.stringify(body):undefined});return r.json();}catch(e){return {error:"network"};}};
|
|
312
|
+
function show(view){["loginView","ownerView","leadView","employeeView","wallView"].forEach(v=>$(v).classList.add("hidden"));const el=$(view);el.classList.remove("hidden");el.classList.remove("anim");void el.offsetWidth;el.classList.add("anim");}
|
|
313
|
+
const LVL={employee:"lvlEmployee",lead:"lvlLead",owner:"lvlOwner"};
|
|
314
|
+
function setWho(){const w=$("who");w.textContent=me?(me.label||me.name):"";const c=$("idChip");if(me){c.style.display="inline-block";c.textContent=me.name.slice(0,1).toUpperCase()+" ยท "+(me.label||me.name)+" ยท "+t(LVL[me.role]||"lvlEmployee");}else{c.style.display="none";}$("logoutBtn").style.display=me?"inline-block":"none";}
|
|
315
|
+
function empty(ico,txt){return '<div class="empty"><span class="ico">'+ico+'</span>'+txt+'</div>';}
|
|
316
|
+
function showMsg(x){$("msg").textContent=x;setTimeout(()=>$("msg").textContent="",2500);}
|
|
317
|
+
async function loadMetrics(into){const m=await api("/api/metrics");into.innerHTML="";const cards=[[t("reports"),m.reports],[t("week"),m.reportsWeek],[t("feedback"),m.feedback],[t("workersActive"),m.workers]];for(const [l,v] of cards){const d=document.createElement("div");d.className="metric";d.innerHTML='<div class="v">'+(v===undefined?"โ":v)+'</div><div class="l">'+l+'</div>';into.appendChild(d);}}
|
|
318
|
+
async function loadUsage(){const tb=$("usageTable")?$("usageTable").querySelector("tbody"):null;if(!tb)return;const r=await api("/api/usage");tb.innerHTML="";
|
|
319
|
+
if(!(r.rows||[]).length){tb.innerHTML='<tr><td colspan="4">'+empty("๐",t("noUsage"))+'</td></tr>';return;}
|
|
320
|
+
(r.rows||[]).forEach(x=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+x.worker+"</td><td>"+x.sessions+"</td><td>"+(x.tokens||0).toLocaleString()+"</td><td>$"+(x.cost||0).toFixed(2)+"</td>";tb.appendChild(tr);});}
|
|
321
|
+
function orderRow(o,canUpdate){
|
|
322
|
+
const d=document.createElement("div");d.className="order";
|
|
323
|
+
const stat=document.createElement("span");stat.className="stat";stat.textContent=t(o.status||"sent");
|
|
324
|
+
d.innerHTML="<b>"+(o.table?((PACK&&PACK.tableLabel&&PACK.tableLabel[cur]?PACK.tableLabel[cur]:"Table")+" "+o.table+" ยท "):"")+o.person+"</b>";
|
|
325
|
+
const txt=document.createElement("span");txt.className="txt";txt.textContent=o.request;
|
|
326
|
+
d.appendChild(txt);d.appendChild(stat);
|
|
327
|
+
if(canUpdate&&o.status!=="delivered"){
|
|
328
|
+
const next=o.status==="sent"?"prep":o.status==="prep"?"ready":"delivered";
|
|
329
|
+
const b=document.createElement("button");b.className="btn small";b.textContent=t(next)+" โ";
|
|
330
|
+
b.onclick=async()=>{await api("/api/live/order",{orderId:o.id,status:next});haptic();renderOrders();};
|
|
331
|
+
d.appendChild(b);
|
|
332
|
+
}
|
|
333
|
+
return d;
|
|
334
|
+
}
|
|
335
|
+
async function renderOrders(){
|
|
336
|
+
const live=await api("/api/live");
|
|
337
|
+
for(const id of ["ownerOrders","leadOrders","workerOrders"]){
|
|
338
|
+
const el=$(id);if(!el)continue;
|
|
339
|
+
el.innerHTML="";
|
|
340
|
+
(live.orders||[]).forEach(o=>el.appendChild(orderRow(o,id!=="workerOrders")));
|
|
341
|
+
if(!(live.orders||[]).length)el.innerHTML=empty("๐ฆ",t("noOrders"));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
$("sayBtn").onclick=async()=>{const v=$("sayText").value.trim();if(!v)return;await api("/api/live/transcript",{worker:me?me.name:"worker",text:v});$("sayText").value="";showMsg(t("processing"));};
|
|
345
|
+
const SR=window.SpeechRecognition||window.webkitSpeechRecognition;
|
|
346
|
+
if(SR){$("micBtn").onclick=()=>{
|
|
347
|
+
if(rec){rec.stop();return;}
|
|
348
|
+
rec=new SR();rec.lang=(cur==="zh"?"zh-CN":cur==="ja"?"ja-JP":cur==="ko"?"ko-KR":cur==="ar"?"ar-SA":cur+"-"+(cur==="en"?"US":cur==="pt"?"PT":cur.toUpperCase()));
|
|
349
|
+
rec.continuous=false;rec.interimResults=false;recording=true;$("micBtn").textContent="โน";
|
|
350
|
+
rec.onresult=async(e)=>{let txt="";for(let i=0;i<e.results.length;i++)txt+=e.results[i][0].transcript;await api("/api/live/transcript",{worker:me?me.name:"worker",text:txt});showMsg(t("processing"));};
|
|
351
|
+
rec.onend=()=>{recording=false;$("micBtn").textContent=t("dictate");rec=null;};
|
|
352
|
+
rec.start();
|
|
353
|
+
};}else{$("micBtn").disabled=true;$("micBtn").textContent=t("micUnsupported");}
|
|
354
|
+
function packFieldsHTML(){if(!PACK||!PACK.fields||!PACK.fields.length)return "";return PACK.fields.map(f=>'<input class="packField" data-fid="'+f.id+'" placeholder="'+(f.label&&f.label[cur]?f.label[cur]:f.id)+'">').join("");}
|
|
355
|
+
async function workerFlow(){
|
|
356
|
+
const live=await api("/api/live");
|
|
357
|
+
const wv=$("employeeView");
|
|
358
|
+
if(!me){return;}
|
|
359
|
+
$("wHome").classList.add("hidden");$("wListen").classList.add("hidden");$("wSummary").classList.add("hidden");
|
|
360
|
+
if(live.status==="listening"){$("wListen").classList.remove("hidden");$("listeningBtn").textContent="๐๏ธ "+ (live.worker||"");$("packFields").innerHTML=packFieldsHTML();$("tableInput").value=live.table||"";}
|
|
361
|
+
else if(live.status==="summary"){$("wSummary").classList.remove("hidden");$("summaryTitle").textContent=t("summaryTitle")+(live.table?(" โ "+(PACK&&PACK.tableLabel&&PACK.tableLabel[cur]?PACK.tableLabel[cur]:"Table")+" "+live.table):"")+Object.entries(live.fields||{}).filter(([k,v])=>v).map(([k,v])=>" ยท "+v).join("");renderSummary(live);}
|
|
362
|
+
else{$("wHome").classList.remove("hidden");}
|
|
363
|
+
renderOrders();
|
|
364
|
+
}
|
|
365
|
+
function renderSummary(live){
|
|
366
|
+
const body=$("summaryBody");body.innerHTML="";
|
|
367
|
+
if(!(live.speakers||[]).length){body.innerHTML='<div class="card"><p class="note">'+t("noSummary")+'</p></div>';return;}
|
|
368
|
+
for(const p of live.speakers){
|
|
369
|
+
const d=document.createElement("div");d.className="person";
|
|
370
|
+
let h='<div class="pname">'+t("person")+" "+(p.id.replace("p",""))+" โ "+p.name+'</div>';
|
|
371
|
+
for(const r of p.requests){
|
|
372
|
+
const confirmed=r.status==="confirmed";
|
|
373
|
+
h+='<div class="req"><span class="txt">'+r.text+'</span>'+
|
|
374
|
+
'<span class="tier tier-'+r.tier+'">'+r.tier+'</span>'+
|
|
375
|
+
'<button class="confirmBtn'+(confirmed?" done":"")+'" data-req="'+r.id+'">'+(confirmed?t("confirmed"):t("confirm"))+'</button></div>';
|
|
376
|
+
}
|
|
377
|
+
d.innerHTML=h;
|
|
378
|
+
d.querySelectorAll(".confirmBtn").forEach(b=>b.onclick=async()=>{
|
|
379
|
+
await api("/api/live/confirm",{requestId:b.dataset.req});
|
|
380
|
+
haptic();
|
|
381
|
+
workerFlow();
|
|
382
|
+
});
|
|
383
|
+
body.appendChild(d);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
$("startBtn").onclick=async()=>{const fields={};document.querySelectorAll(".packField").forEach(i=>{fields[i.dataset.fid]=i.value.trim();});await api("/api/live/start",{worker:me.name,table:$("tableInput").value.trim()||null,fields});workerFlow();};
|
|
387
|
+
$("stopBtn").onclick=async()=>{const live=await api("/api/live");if((live.speakers||[]).length){live.status="summary";await api("/api/live/summary",{speakers:live.speakers});}else{await api("/api/live/close",{});}workerFlow();};
|
|
388
|
+
$("newConvBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
|
|
389
|
+
$("toHomeBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
|
|
390
|
+
async function enter(){
|
|
391
|
+
if(!PACK){PACK=await api("/api/sector");applyPack();}
|
|
392
|
+
setWho();
|
|
393
|
+
if(me.role==="owner"){show("ownerView");loadMetrics($("ownerMetrics"));loadUsers();loadField();loadRules();loadUsage();renderOrders();loadPresets();}
|
|
394
|
+
else if(me.role==="lead"){show("leadView");loadMetrics($("leadMetrics"));loadLead();renderOrders();if(kitchenPoll)clearInterval(kitchenPoll);kitchenPoll=setInterval(kitchenWatch,4000);}
|
|
395
|
+
else{show("employeeView");$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();if(livePoll)clearInterval(livePoll);livePoll=setInterval(()=>{if(me&&me.role==="employee")workerFlow();},3000);}
|
|
396
|
+
}
|
|
397
|
+
let pwVisible=false;
|
|
398
|
+
$("eyeBtn").onclick=()=>{pwVisible=!pwVisible;$("loginPass").type=pwVisible?"text":"password";$("eyeOn").classList.toggle("hidden",pwVisible);$("eyeOff").classList.toggle("hidden",!pwVisible);};
|
|
399
|
+
$("loginBtn").onclick=async()=>{
|
|
400
|
+
const err=$("loginError");
|
|
401
|
+
err.classList.add("hidden");
|
|
402
|
+
const u=$("loginUser").value.trim(),p=$("loginPass").value;
|
|
403
|
+
if(!u||!p){err.textContent=t("fillBoth");err.classList.remove("hidden");return;}
|
|
404
|
+
$("loginBtn").disabled=true;$("loginBtn").textContent=t("loggingIn");
|
|
405
|
+
const r=await api("/api/login",{user:u,password:p});
|
|
406
|
+
$("loginBtn").disabled=false;$("loginBtn").textContent=t("loginBtn");
|
|
407
|
+
if(r.error){err.textContent=r.error==="network"?t("cannotReach"):t("loginFailed");err.classList.remove("hidden");return;}
|
|
408
|
+
err.classList.add("hidden");
|
|
409
|
+
token=r.token;me={name:r.name,role:r.role,label:r.label||r.name};
|
|
410
|
+
sessionStorage.setItem("dsh-sup-token",token);sessionStorage.setItem("dsh-sup-me",JSON.stringify(me));
|
|
411
|
+
$("loginPass").value="";enter();
|
|
412
|
+
};
|
|
413
|
+
function logout(){api("/api/logout",{});token=null;me=null;sessionStorage.clear();if(livePoll)clearInterval(livePoll);if(kitchenPoll)clearInterval(kitchenPoll);setWho();show("loginView");}
|
|
414
|
+
$("logoutBtn").onclick=logout;
|
|
415
|
+
const sb=$("switchBtn");if(sb)sb.onclick=logout;
|
|
416
|
+
async function loadUsers(){const r=await api("/api/users");const tb=$("usersTable").querySelector("tbody");tb.innerHTML="";(r.users||[]).forEach(u=>{const tr=document.createElement("tr");tr.innerHTML="<td>"+u.name+"</td><td>"+(u.label||u.name)+" ยท "+t(LVL[u.role]||"lvlEmployee")+"</td>";tb.appendChild(tr);});}
|
|
417
|
+
$("addUserBtn").onclick=async()=>{const r=await api("/api/users",{name:$("newUser").value,password:$("newPass").value,role:$("newRole").value,label:$("newLabel").value});showMsg(r.error?"Error: "+r.error:t("workerAdded"));if(!r.error){loadUsers();$("newUser").value=$("newPass").value="";}};
|
|
418
|
+
async function loadField(){const rc=(await api("/api/reports")).content;if(rc){$("reports").innerHTML="<pre>"+rc+"</pre>";}else{$("reports").innerHTML=empty("๐",t("noReports"));}const fc=(await api("/api/feedback")).content;if(fc){$("feedback").innerHTML="<pre>"+fc+"</pre>";}else{$("feedback").innerHTML=empty("๐ฌ",t("feedbackQueue"));}const live=await api("/api/live");const ib=(live.inbox||[]).map(x=>"[โข] "+x.worker+": "+x.text).join("\n");if(ib){$("trail").innerHTML="<pre>"+ib+"</pre>";}else{$("trail").innerHTML=empty("๐๏ธ",t("conversationTrail"));}}
|
|
419
|
+
async function loadLead(){$("leadReports").textContent=(await api("/api/reports")).content||"(empty)";$("leadFeedback").textContent=(await api("/api/feedback")).content||"(empty)";}
|
|
420
|
+
$("refreshReports").onclick=loadField;$("leadRefresh").onclick=loadLead;
|
|
421
|
+
const ar=$("autoRefresh");
|
|
422
|
+
if(ar)ar.onclick=()=>{auto=!auto;ar.textContent=auto?t("autoOn"):t("autoOff");if(auto){const iv=setInterval(()=>{if(!auto){clearInterval(iv);return;}if(me&&me.role==="owner"){loadField();renderOrders();}},30000);}};
|
|
423
|
+
async function loadPresets(){
|
|
424
|
+
const r=await api("/api/sector-presets");
|
|
425
|
+
const g=$("presetGrid");if(!g)return;g.innerHTML="";
|
|
426
|
+
(r.presets||[]).forEach(p=>{const b=document.createElement("button");b.className="btn small gray";b.textContent=p.id;b.onclick=async()=>{await api("/api/sector",p);PACK=p;applyPack();showMsg(t("sectorSaved"));renderSuggest();};g.appendChild(b);});
|
|
427
|
+
renderSuggest();
|
|
428
|
+
}
|
|
429
|
+
function renderSuggest(){const el=$("suggestUsers");if(!el||!PACK||!PACK.suggestedUsers)return;el.innerHTML="";(PACK.suggestedUsers||[]).forEach(su=>{const b=document.createElement("button");b.className="btn small gray";b.textContent="+ "+(su.label&&(su.label[cur]||su.label.en)||su.level);b.onclick=()=>{$("newUser").value="";$("newLabel").value=su.label&&(su.label[cur]||su.label.en)||"";$("newRole").value=su.level;};el.appendChild(b);});}
|
|
430
|
+
$("saveSectorBtn").onclick=async()=>{
|
|
431
|
+
const pack={id:$("csId").value.trim()||"custom",
|
|
432
|
+
tableLabel:{en:$("csLabelEn").value.trim()||"Table",fr:$("csLabelFr").value.trim(),es:$("csLabelEn").value.trim()||"Table"},
|
|
433
|
+
ordersTarget:{en:$("csOrdersEn").value.trim()||"Orders",fr:$("csOrdersFr").value.trim()},
|
|
434
|
+
entity:{en:"person",fr:"personne"},
|
|
435
|
+
fields:[]};
|
|
436
|
+
if($("csF1Id").value.trim())pack.fields.push({id:$("csF1Id").value.trim(),type:"text",label:{en:$("csF1Label").value.trim()||$("csF1Id").value.trim()}});
|
|
437
|
+
if($("csF2Id").value.trim())pack.fields.push({id:$("csF2Id").value.trim(),type:"text",label:{en:$("csF2Label").value.trim()||$("csF2Id").value.trim()}});
|
|
438
|
+
const r=await api("/api/sector",pack);showMsg(r.error?"Error":t("sectorSaved"));PACK=pack;applyPack();
|
|
439
|
+
};
|
|
440
|
+
$("aiSectorBtn").onclick=async()=>{
|
|
441
|
+
const prompt="Live mirror mode (workflow-master). Design a sector pack JSON for this business, in this exact shape: {\"id\":\"<sector-id>\",\"tableLabel\":{\"en\":\"<entity label>\",\"es\":\"โฆ\",\"fr\":\"โฆ\"},\"ordersTarget\":{\"en\":\"<orders title>\",\"fr\":\"โฆ\"},\"entity\":{\"en\":\"<entity>\",\"fr\":\"โฆ\"},\"fields\":[{\"id\":\"<field>\",\"type\":\"number|text\",\"label\":{\"en\":\"<label>\",\"fr\":\"โฆ\"}}]}. Describe your business here: "+($("csLabelEn").value||"(your business)")+". Reply ONLY with the JSON.";
|
|
442
|
+
try{await navigator.clipboard.writeText(prompt);}catch(e){}
|
|
443
|
+
showMsg(t("aiSectorCopied"));
|
|
444
|
+
};
|
|
445
|
+
async function loadRules(){$("decisions").value=(await api("/api/decisions")).content||"";}
|
|
446
|
+
$("saveDecisions").onclick=async()=>{await api("/api/decisions",{content:$("decisions").value});$("decisionsSaved").textContent=t("saved");setTimeout(()=>$("decisionsSaved").textContent="",2000);};
|
|
447
|
+
document.querySelectorAll(".tabs button").forEach(b=>b.onclick=()=>{document.querySelectorAll(".tabs button").forEach(x=>x.classList.remove("active"));b.classList.add("active");["overview","field","rules","sector"].forEach(x=>$("tab-"+x).classList.add("hidden"));$("tab-"+b.dataset.tab).classList.remove("hidden");});
|
|
448
|
+
$("reportBtn").onclick=async()=>{const r=await api("/api/report",{text:$("reportText").value});if(r.error){showMsg("Error: "+r.error);return;}$("reportText").value="";showMsg(t("reportSent"));};
|
|
449
|
+
$("empFbBtn").onclick=async()=>{const r=await api("/api/feedback",{worker:me.name,role:me.role,category:$("empFbCat").value,text:$("empFbText").value});if(r.error){showMsg("Error: "+r.error);return;}$("empFbText").value="";showMsg(t("feedbackSent"));};
|
|
450
|
+
const st=sessionStorage.getItem("dsh-sup-token");
|
|
451
|
+
if(st){token=st;me=JSON.parse(sessionStorage.getItem("dsh-sup-me")||"null");(async()=>{const r=await api("/api/me");if(!r||!r.name){logout();return;}enter();})();}
|
|
452
|
+
else setWho();
|
|
453
|
+
async function wallTick(){try{const r=await (await fetch("/api/wall")).json();const cards=[[t("week"),r.reportsWeek],[t("feedback"),r.feedback],[t("workersActive"),r.workers],[t("reportsTotal"),r.reports]];$("wallCards").innerHTML=cards.map(c=>'<div class="wall-card"><div class="v">'+(c[1]===undefined?"โ":c[1])+'</div><div class="l">'+c[0]+'</div></div>').join("");$("wallFeed").textContent=r.feedbackTail||t("noActivity");}catch(e){$("wallFeed").textContent=t("cannotReach");}}
|
|
454
|
+
if(location.search.indexOf("wall=1")>=0){
|
|
455
|
+
document.body.classList.add("wall");show("wallView");
|
|
456
|
+
wallTick();setInterval(wallTick,30000);
|
|
457
|
+
}
|
|
458
|
+
</script>
|
|
459
|
+
</body>
|
|
460
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "DSH Assistant โ Action Panel",
|
|
3
|
+
"short_name": "DSH Assistant",
|
|
4
|
+
"description": "One-button listening for the J.Franco Agentic Workflow Suite on DeepSeek Harness. The AI listens, works, proposes, and reports โ you verify and decide.",
|
|
5
|
+
"start_url": "./panel.html",
|
|
6
|
+
"scope": "./",
|
|
7
|
+
"display": "standalone",
|
|
8
|
+
"orientation": "any",
|
|
9
|
+
"background_color": "#f6f7fb",
|
|
10
|
+
"theme_color": "#4D6BFE",
|
|
11
|
+
"lang": "en",
|
|
12
|
+
"categories": ["productivity", "business", "utilities"],
|
|
13
|
+
"icons": [
|
|
14
|
+
{ "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
|
|
15
|
+
{ "src": "icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
|
|
16
|
+
]
|
|
17
|
+
}
|