// drover-workshop.jsx — Workshop: industrial slate + amber accent. Subtle texture. const WSH = { bg: '#181a1d', chrome: '#121417', panel: '#1f2226', panel2: '#23272c', border: '#2c3036', borderSoft: '#222529', text: '#e5e3df', dim: '#9a958c', dimmer: '#5e5b56', accent: '#e89a3c', accentSoft: 'rgba(232,154,60,0.15)', danger: '#d56654', warn: '#d4a248', pass: '#7fb37b', skip: '#7c7872', inputBg: '#141619', primaryFg: '#1a120a', }; function WorkshopWindow({ initial }) { const t = WSH; const D = window.useDrover(initial); const palette = { pending: t.dimmer, running: t.accent, passed: t.pass, failed: t.danger, skipped: t.skip }; const fontUI = '"IBM Plex Sans","Inter",system-ui,sans-serif'; const fontMono = '"IBM Plex Mono","JetBrains Mono",ui-monospace,monospace'; const isActive = D.phase === 'active'; return (
{/* subtle grain */}
{/* title — workshop label tag */}
Drover-Go v0.4.2
{[, , ].map((ic,i) => (
{ic}
))}
{/* form */} SOCKS5 PROXY
D.update({ host: v })} placeholder="95.165.72.59 / example.com" onSubmit={D.runCheck} fontUI={fontUI}/> D.update({ port: v.replace(/\D/g,'') })} placeholder="12334" inputMode="numeric" onSubmit={D.runCheck} fontUI={fontUI}/>
{ D.update({ auth: v }); if (v) setTimeout(()=>document.getElementById('wsh-login')?.focus(),30); }}> AUTHENTICATION
D.update({ login: v })} placeholder="user" onSubmit={D.runCheck} fontUI={fontUI}/> D.update({ password: v })} placeholder="••••••" onSubmit={D.runCheck} fontUI={fontUI}/>
STATUS
{D.phase === 'idle' ?
Ready to check
: }
{isActive && (
)}
); } function WshHead({ t, children, right }) { return (
{children}
{right &&
{right}
}
); } function WshField({ t, label, children, style }) { return ; } function WshInput({ t, value, onChange, type, placeholder, onSubmit, disabled, id, fontUI, inputMode }) { return onChange(e.target.value)} placeholder={placeholder} onKeyDown={e => e.key === 'Enter' && onSubmit?.()} style={{ background: t.inputBg, color: disabled ? t.dimmer : t.text, border:`1px solid ${t.border}`, borderRadius: 1, padding:'8px 10px', fontSize: 13, fontFamily: fontUI, outline:'none', width:'100%', boxSizing:'border-box', }}/>; } function WshSwitch({ t, checked, onChange, children }) { return ( ); } function WshStatus({ t, D, palette, fontMono }) { return (
{D.phase === 'checking' ?
Running diagnostics…
:
{D.lastSummary?.failed === 0 ? 'All checks passed. Ready to start.' : `${D.lastSummary?.failed} of ${D.tests.length} checks failed. Some features won't work.`}
}
{D.tests.map(test => { const r = D.results[test.id]; const state = r?.result || (D.running === test.id ? 'running' : 'pending'); return (
{test.label} {r?.metric} {r?.result === 'failed' && ( )}
{r?.result === 'failed' && r.expanded && (
{r.error}
{r.hint}
)}
); })}
); } function WshStartBtn({ t, D, fontUI }) { const allFailed = D.lastSummary && D.lastSummary.failed === D.tests.length; const ok = D.phase === 'checked' && !allFailed; const active = D.phase === 'active'; const warning = active && (D.lastSummary?.failed||0) > 0; if (active) { const c = warning ? t.warn : t.pass; return (
Active{warning ? ' · UDP warn' : ''}
); } return ; } function WshStopBtn({ t, D, fontUI }) { const enabled = D.phase === 'active'; return ; } function Stat({ val, lbl, t, fontMono, hl }) { return
{lbl} {val}
; } function WshLogs({ t, D, fontMono }) { return (
{D.logsOpen && ( <>
{[['copy', () => navigator.clipboard?.writeText(D.logs.map(x=>`[${x.level}] ${x.msg}`).join('\n'))], ['clear', D.clearLogs], ['file', null]].map(([l, fn]) => ( ))}
el && (el.scrollTop = el.scrollHeight)} style={{ maxHeight: 130, overflowY:'auto', padding:'8px 16px', fontFamily: fontMono, fontSize: 10.5, lineHeight: 1.6, color: t.dim, background: t.panel }}> {D.logs.map((l,i) => (
{window.fmtTime(l.t)}{' '} [{l.level}]{' '} {l.msg}
))}
)}
); } window.WorkshopWindow = WorkshopWindow;