113616b039
Release / release (push) Successful in 3m19s
Stash the full claude.ai/design output (12 JSX variants — brutalist, classic, cli, compact, fluent-live, glass, hero-live, minimal, sketches, studio, wizard-live, workshop — plus shared hooks and a standalone HTML preview) for reference when we get to the Wails frontend in Phase 6/7. Source archive: C:\Users\root\Downloads\app(1).zip (~1MB). Not wired into any build target yet — current GUI is the temporary MessageBox stub. Pulling these in is the goal of the Wails phase. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
336 lines
16 KiB
React
336 lines
16 KiB
React
// drover-brutalist.jsx — Variant 4: Brutalist.
|
||
// Hard borders, no rounding. Heavy mono. Monochrome + one acid lime accent.
|
||
// Block-style "DOS-meets-zine" feeling. All-caps labels.
|
||
|
||
const BrutTheme = {
|
||
d: {
|
||
bg: '#0c0c0c', panel: '#0c0c0c', alt: '#161616',
|
||
border: '#f4f4f4', borderDim: '#3a3a3a',
|
||
text: '#f4f4f4', dim: '#a8a8a8', dimmer: '#6a6a6a',
|
||
accent: '#c6ff00', danger: '#ff3a52', warn: '#ffaa00', pass: '#7eff84', skip: '#888',
|
||
inputBg: '#0c0c0c', primaryFg: '#0c0c0c',
|
||
},
|
||
l: {
|
||
bg: '#f4f1ea', panel: '#f4f1ea', alt: '#e9e5d8',
|
||
border: '#0c0c0c', borderDim: '#bfb9a8',
|
||
text: '#0c0c0c', dim: '#3a3a3a', dimmer: '#7a7568',
|
||
accent: '#7d8f00', danger: '#b81e34', warn: '#a86c00', pass: '#1a7e2c', skip: '#7a7568',
|
||
inputBg: '#f4f1ea', primaryFg: '#f4f1ea',
|
||
},
|
||
};
|
||
|
||
function BrutWindow({ mode = 'dark', initial }) {
|
||
const t = BrutTheme[mode === 'dark' ? 'd' : 'l'];
|
||
const D = window.useDrover(initial);
|
||
const palette = { pending: t.dimmer, running: t.accent, passed: t.pass, failed: t.danger, skipped: t.skip };
|
||
const isActive = D.phase === 'active';
|
||
const fontMono = '"JetBrains Mono","IBM Plex Mono","Space Mono",ui-monospace,monospace';
|
||
|
||
return (
|
||
<div style={{
|
||
width: 480, height: 640, background: t.bg, color: t.text, display: 'flex', flexDirection: 'column',
|
||
fontFamily: fontMono, fontSize: 12, overflow: 'hidden',
|
||
border: `2px solid ${t.border}`, boxSizing:'border-box',
|
||
}}>
|
||
<BrutTitle t={t}/>
|
||
|
||
<div style={{ flex: 1, overflow:'auto' }}>
|
||
{/* form */}
|
||
<div style={{ padding: 14, borderBottom: `2px solid ${t.border}` }}>
|
||
<BrutLabel t={t}>// SOCKS5 PROXY</BrutLabel>
|
||
<div style={{ display:'flex', gap: 8 }}>
|
||
<BField t={t} label="HOST" style={{ flex: 1 }}>
|
||
<input value={D.form.host} onChange={e => D.update({ host: e.target.value })}
|
||
placeholder="95.165.72.59 / example.com"
|
||
onKeyDown={e => e.key === 'Enter' && D.runCheck()} style={brutInput(t, fontMono)}/>
|
||
</BField>
|
||
<BField t={t} label="PORT" style={{ width: 92 }}>
|
||
<input value={D.form.port} onChange={e => D.update({ port: e.target.value.replace(/\D/g,'') })}
|
||
placeholder="12334" inputMode="numeric"
|
||
onKeyDown={e => e.key === 'Enter' && D.runCheck()} style={brutInput(t, fontMono)}/>
|
||
</BField>
|
||
</div>
|
||
<div style={{ height: 10 }}/>
|
||
<BrutCheckbox t={t} checked={D.form.auth}
|
||
onChange={(v) => { D.update({ auth: v }); if (v) setTimeout(()=>document.getElementById('br-login')?.focus(),30); }}>
|
||
AUTHENTICATION
|
||
</BrutCheckbox>
|
||
<div style={{ display:'flex', gap: 8, marginTop: 8, opacity: D.form.auth ? 1 : 0.4,
|
||
pointerEvents: D.form.auth ? 'auto':'none' }}>
|
||
<BField t={t} label="LOGIN" style={{ flex: 1 }}>
|
||
<input id="br-login" disabled={!D.form.auth} value={D.form.login}
|
||
onChange={e => D.update({ login: e.target.value })} placeholder="user"
|
||
onKeyDown={e => e.key === 'Enter' && D.runCheck()} style={brutInput(t, fontMono, !D.form.auth)}/>
|
||
</BField>
|
||
<BField t={t} label="PASSWORD" style={{ flex: 1 }}>
|
||
<input disabled={!D.form.auth} type="password" value={D.form.password}
|
||
onChange={e => D.update({ password: e.target.value })} placeholder="******"
|
||
onKeyDown={e => e.key === 'Enter' && D.runCheck()} style={brutInput(t, fontMono, !D.form.auth)}/>
|
||
</BField>
|
||
</div>
|
||
<div style={{ height: 12 }}/>
|
||
<BrutPrimary t={t} onClick={D.runCheck} disabled={D.phase === 'checking' || isActive}>
|
||
{D.phase === 'checking' ? '>> CHECKING…' : '>> CHECK CONNECTION'}
|
||
</BrutPrimary>
|
||
</div>
|
||
|
||
{/* status */}
|
||
<div style={{ padding: 14, borderBottom: `2px solid ${t.border}` }}>
|
||
<BrutLabel t={t}>// STATUS</BrutLabel>
|
||
<BrutStatus t={t} D={D} palette={palette}/>
|
||
</div>
|
||
|
||
{/* actions */}
|
||
<div style={{ padding: 14 }}>
|
||
<div style={{ display:'flex', gap: 8 }}>
|
||
<BrutStartBtn t={t} D={D}/>
|
||
<BrutStopBtn t={t} D={D}/>
|
||
</div>
|
||
{isActive && <BrutLiveStats t={t} stats={D.stats}/>}
|
||
</div>
|
||
</div>
|
||
|
||
<BrutLogs t={t} D={D}/>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function BrutTitle({ t }) {
|
||
const cell = { width: 36, height: 28, display:'flex', alignItems:'center', justifyContent:'center', cursor:'pointer',
|
||
borderLeft: `2px solid ${t.border}`, color: t.text };
|
||
return (
|
||
<div style={{
|
||
height: 30, background: t.alt, display:'flex', alignItems:'center',
|
||
borderBottom: `2px solid ${t.border}`, userSelect:'none',
|
||
}}>
|
||
<div style={{ display:'flex', alignItems:'center', gap: 8, padding:'0 12px', flex:1 }}>
|
||
<span style={{
|
||
width: 16, height: 16, background: t.accent, color: '#0c0c0c',
|
||
display:'flex', alignItems:'center', justifyContent:'center', fontWeight: 700, fontSize: 11,
|
||
}}>D</span>
|
||
<span style={{ fontSize: 11, fontWeight: 700, letterSpacing: 1.5 }}>DROVER-GO</span>
|
||
<span style={{ fontSize: 10, color: t.dim }}>[v0.4.2]</span>
|
||
</div>
|
||
<div style={{ display:'flex' }}>
|
||
<div style={cell} title="Settings"><window.IconGear color={t.text}/></div>
|
||
<div style={cell} title="Minimize"><window.IconMin color={t.text}/></div>
|
||
<div style={{ ...cell, background: t.danger, color: '#fff' }} title="Close"><window.IconClose color="#fff"/></div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
function BrutLabel({ t, children }) {
|
||
return <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: 1.5, marginBottom: 10, color: t.dim }}>{children}</div>;
|
||
}
|
||
function BField({ t, label, children, style }) {
|
||
return <label style={{ display:'flex', flexDirection:'column', gap: 4, ...style }}>
|
||
<span style={{ fontSize: 10, color: t.dim, fontWeight: 700, letterSpacing: 1 }}>{label}</span>{children}
|
||
</label>;
|
||
}
|
||
function brutInput(t, fontMono, disabled) {
|
||
return {
|
||
background: t.inputBg, color: disabled ? t.dimmer : t.text,
|
||
border: `2px solid ${disabled ? t.borderDim : t.border}`, borderRadius: 0,
|
||
padding: '7px 9px', fontSize: 12, fontFamily: fontMono, outline:'none',
|
||
width:'100%', boxSizing:'border-box',
|
||
};
|
||
}
|
||
function BrutCheckbox({ t, checked, onChange, children }) {
|
||
return (
|
||
<label style={{ display:'inline-flex', alignItems:'center', gap: 8, cursor:'pointer', userSelect:'none' }}>
|
||
<span style={{
|
||
width: 16, height: 16, border: `2px solid ${t.border}`,
|
||
background: checked ? t.accent : 'transparent',
|
||
display:'flex', alignItems:'center', justifyContent:'center',
|
||
}}>
|
||
{checked && <span style={{ fontWeight: 900, color: '#0c0c0c', fontSize: 12, lineHeight: 1 }}>×</span>}
|
||
</span>
|
||
<input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)} style={{ display:'none' }}/>
|
||
<span style={{ fontSize: 11, fontWeight: 700, letterSpacing: 1 }}>{children}</span>
|
||
</label>
|
||
);
|
||
}
|
||
function BrutPrimary({ t, onClick, disabled, children, style }) {
|
||
return (
|
||
<button onClick={onClick} disabled={disabled} style={{
|
||
width:'100%', padding: '10px 12px', border: `2px solid ${t.border}`, borderRadius: 0,
|
||
background: disabled ? t.alt : t.accent, color: disabled ? t.dimmer : t.primaryFg,
|
||
fontWeight: 700, fontSize: 12, letterSpacing: 1.2, cursor: disabled?'not-allowed':'pointer',
|
||
fontFamily: 'inherit', textAlign:'left',
|
||
boxShadow: disabled ? 'none' : `4px 4px 0 ${t.border}`,
|
||
transition: 'transform .08s, box-shadow .08s',
|
||
...style,
|
||
}}
|
||
onMouseDown={e => { if (!disabled) { e.currentTarget.style.transform='translate(2px,2px)'; e.currentTarget.style.boxShadow=`2px 2px 0 ${t.border}`; }}}
|
||
onMouseUp={e => { if (!disabled) { e.currentTarget.style.transform=''; e.currentTarget.style.boxShadow=`4px 4px 0 ${t.border}`; }}}
|
||
onMouseLeave={e => { if (!disabled) { e.currentTarget.style.transform=''; e.currentTarget.style.boxShadow=`4px 4px 0 ${t.border}`; }}}
|
||
>{children}</button>
|
||
);
|
||
}
|
||
function BrutStatus({ t, D, palette }) {
|
||
if (D.phase === 'idle') {
|
||
return (
|
||
<div style={{ display:'flex', alignItems:'center', gap: 9, padding: '4px 0' }}>
|
||
<span style={{ width: 10, height: 10, border: `2px solid ${t.dim}`, background: 'transparent' }}/>
|
||
<span style={{ color: t.dim, fontSize: 11.5, letterSpacing: 0.5 }}>READY TO CHECK_</span>
|
||
</div>
|
||
);
|
||
}
|
||
return (
|
||
<div>
|
||
{D.phase === 'checking'
|
||
? <div style={{ display:'flex', alignItems:'center', gap: 9, marginBottom: 10 }}>
|
||
<window.StatusDot state="running" palette={palette} size={14}/>
|
||
<span style={{ fontWeight: 700, fontSize: 11.5, letterSpacing: 0.7 }}>RUNNING DIAGNOSTICS…</span>
|
||
</div>
|
||
: <div style={{
|
||
padding: '7px 10px', marginBottom: 10,
|
||
background: D.lastSummary?.failed === 0 ? t.accent : t.warn,
|
||
color: '#0c0c0c', fontWeight: 700, fontSize: 11.5, letterSpacing: 0.5,
|
||
border: `2px solid ${t.border}`,
|
||
}}>
|
||
{D.lastSummary?.failed === 0
|
||
? '▮ ALL CHECKS PASSED. READY TO START.'
|
||
: `▮ ${D.lastSummary?.failed}/${D.tests.length} FAILED · SOME FEATURES BROKEN`}
|
||
</div>}
|
||
<div style={{ border: `2px solid ${t.border}` }}>
|
||
{D.tests.map((test, i) => {
|
||
const r = D.results[test.id];
|
||
const state = r?.result || (D.running === test.id ? 'running' : 'pending');
|
||
const last = i === D.tests.length - 1;
|
||
return (
|
||
<div key={test.id} style={{ borderBottom: !last ? `1px solid ${t.borderDim}` : 'none' }}>
|
||
<div style={{ display:'flex', alignItems:'center', gap: 9, height: 26, padding: '0 9px' }}>
|
||
<window.StatusDot state={state} palette={palette} size={12}/>
|
||
<span style={{ color: state==='pending'?t.dim:t.text, fontSize: 11.5 }} title={test.desc}>
|
||
{test.label}
|
||
</span>
|
||
<span style={{ marginLeft:'auto', fontSize: 10.5,
|
||
color: state==='failed'?t.danger:state==='skipped'?t.skip:state==='passed'?t.pass:t.dim }}>
|
||
{r?.metric || (state==='running'?'…':'')}
|
||
</span>
|
||
{r?.result === 'failed' && (
|
||
<button onClick={() => D.toggleExpand(test.id)} style={{
|
||
background:'transparent', border:'none', cursor:'pointer', padding: 4, color: t.text,
|
||
}}><window.IconChevron color={t.text} dir={r.expanded?'up':'down'}/></button>
|
||
)}
|
||
</div>
|
||
{r?.result === 'failed' && r.expanded && (
|
||
<div className="drv-fadein" style={{
|
||
borderTop: `1px solid ${t.borderDim}`,
|
||
background: t.alt, padding: 10, fontSize: 11,
|
||
}}>
|
||
<div style={{ color: t.danger, fontWeight: 700, marginBottom: 4, letterSpacing: 0.5 }}>! {r.error}</div>
|
||
<div style={{ color: t.dim, lineHeight: 1.5 }}>{r.hint}</div>
|
||
<button onClick={() => navigator.clipboard?.writeText(`[${test.label}] ${r.error}`)}
|
||
style={{
|
||
marginTop: 8, background: 'transparent', border: `1.5px solid ${t.border}`,
|
||
color: t.text, padding: '3px 8px', fontSize: 10, cursor:'pointer',
|
||
fontFamily: 'inherit', letterSpacing: 0.5, fontWeight: 700,
|
||
}}>[ COPY ERROR ]</button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
function BrutStartBtn({ t, D }) {
|
||
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) {
|
||
return (
|
||
<div style={{
|
||
flex: 1, padding: '10px 12px', border: `2px solid ${t.border}`,
|
||
background: warning ? t.warn : t.accent, color: '#0c0c0c',
|
||
fontWeight: 700, fontSize: 12, letterSpacing: 1.2, fontFamily: 'inherit',
|
||
display:'flex', alignItems:'center', justifyContent:'center', gap: 8,
|
||
boxShadow: `4px 4px 0 ${t.border}`,
|
||
}}>
|
||
<span className="drv-pulsedot" style={{ width: 9, height: 9, background: '#0c0c0c' }}/>
|
||
●{warning ? ' ACTIVE / UDP-WARN' : ' ACTIVE'}
|
||
</div>
|
||
);
|
||
}
|
||
return <BrutPrimary t={t} disabled={!ok} onClick={D.startProxy} style={{ flex: 1 }}>{'>> START PROXYING'}</BrutPrimary>;
|
||
}
|
||
function BrutStopBtn({ t, D }) {
|
||
const enabled = D.phase === 'active';
|
||
return (
|
||
<button onClick={D.stopProxy} disabled={!enabled} style={{
|
||
flex: 1, padding: '10px 12px', border: `2px solid ${enabled?t.border:t.borderDim}`,
|
||
background: t.bg, color: enabled ? t.text : t.dimmer,
|
||
fontWeight: 700, fontSize: 12, letterSpacing: 1.2, fontFamily: 'inherit',
|
||
cursor: enabled ? 'pointer':'not-allowed', textAlign:'left',
|
||
boxShadow: enabled ? `4px 4px 0 ${t.border}` : 'none',
|
||
}}>{'■ STOP'}</button>
|
||
);
|
||
}
|
||
function BrutLiveStats({ t, stats }) {
|
||
const C = ({ icon, val, lbl }) => (
|
||
<div style={{ display:'flex', alignItems:'center', gap: 4 }}>
|
||
{icon}<span style={{ fontSize: 11, fontWeight: 700 }}>{val}</span>
|
||
{lbl && <span style={{ fontSize: 9, color: t.dim, fontWeight: 700 }}>{lbl}</span>}
|
||
</div>
|
||
);
|
||
return (
|
||
<div style={{
|
||
marginTop: 10, padding: '7px 10px', border: `2px solid ${t.border}`,
|
||
display:'flex', justifyContent:'space-between', alignItems:'center',
|
||
}}>
|
||
<C icon={<window.IconArrowUp color={t.text}/>} val={window.fmtBytes(stats.up)}/>
|
||
<C icon={<window.IconArrowDown color={t.text}/>} val={window.fmtBytes(stats.down)}/>
|
||
<C val={stats.tcp} lbl="TCP"/>
|
||
<C val={stats.udp} lbl="UDP"/>
|
||
<C val={window.fmtUptime(stats.uptimeS)} lbl="UP"/>
|
||
</div>
|
||
);
|
||
}
|
||
function BrutLogs({ t, D }) {
|
||
return (
|
||
<div style={{ borderTop: `2px solid ${t.border}`, background: t.alt, flexShrink: 0 }}>
|
||
<button onClick={() => D.setLogsOpen(!D.logsOpen)} style={{
|
||
width:'100%', padding: '7px 14px', display:'flex', alignItems:'center', gap: 9,
|
||
background:'transparent', border:'none', color: t.text, cursor:'pointer',
|
||
fontSize: 11, fontFamily: 'inherit', fontWeight: 700, letterSpacing: 1.2,
|
||
}}>
|
||
<window.IconChevron color={t.text} dir={D.logsOpen ? 'down' : 'right'}/>
|
||
<span>// LOGS</span>
|
||
<span style={{ marginLeft: 'auto', color: t.dim }}>{D.logs.length} LINES</span>
|
||
</button>
|
||
{D.logsOpen && (
|
||
<>
|
||
<div style={{ display:'flex', gap: 6, padding: '0 14px 7px' }}>
|
||
{[['COPY ALL', () => navigator.clipboard?.writeText(D.logs.map(x=>`[${x.level}] ${x.msg}`).join('\n'))],
|
||
['CLEAR', D.clearLogs], ['OPEN FILE', null]].map(([l, fn]) => (
|
||
<button key={l} onClick={fn || undefined} style={{
|
||
background:'transparent', border:`1.5px solid ${t.border}`, color: t.text,
|
||
padding: '3px 8px', fontSize: 9.5, fontWeight: 700, letterSpacing: 1, cursor:'pointer',
|
||
fontFamily:'inherit',
|
||
}}>[ {l} ]</button>
|
||
))}
|
||
</div>
|
||
<div className="drv-log" ref={el => el && (el.scrollTop = el.scrollHeight)}
|
||
style={{ maxHeight: 130, overflowY: 'auto', padding: '7px 14px', fontSize: 10.5, lineHeight: 1.6, color: t.text }}>
|
||
{D.logs.map((l,i) => (
|
||
<div key={i}>
|
||
<span style={{ color: t.dim }}>{window.fmtTime(l.t)}</span>{' '}
|
||
<span style={{
|
||
color: l.level==='ERROR'?t.danger:l.level==='WARN'?t.warn:t.accent, fontWeight: 700,
|
||
}}>[{l.level}]</span>{' '}
|
||
{l.msg}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
window.BrutWindow = BrutWindow;
|