solvox / src /renderer /pages /SettingsPage.tsx
muthuk1's picture
🎨 Complete Coinbase design system rebuild: white canvas, single blue accent, pill CTAs, editorial spacing, hairline borders, dark hero bands, asset rows, mono numbers, 96px section rhythm
5f5514e verified
import React, { useState } from 'react';
interface Props { onLock: () => void; }
const models = [
{ name: 'LLM', model: 'Llama 3.2 3B Instruct', q: 'Q4_K_M', size: '2.0 GB', pkg: 'llm-llamacpp' },
{ name: 'Embeddings', model: 'Nomic Embed Text v1.5', q: 'Q4_K_M', size: '260 MB', pkg: 'embed-llamacpp' },
{ name: 'Speech-to-Text', model: 'Whisper Base.en', q: 'GGML', size: '150 MB', pkg: 'transcription-whispercpp' },
{ name: 'Text-to-Speech', model: 'Piper Amy', q: 'ONNX', size: '75 MB', pkg: 'tts-onnx' },
{ name: 'Translation', model: 'OPUS MT (EN↔ES)', q: 'NMT', size: '50 MB', pkg: 'translation-nmtcpp' },
{ name: 'OCR', model: 'PaddleOCR v4', q: 'ONNX', size: '30 MB', pkg: 'ocr-onnx' },
];
export default function SettingsPage({ onLock }: Props) {
const [network, setNetwork] = useState('devnet');
return (
<div className="max-w-2xl mx-auto px-8 py-section">
<h2 className="display-text text-title-lg text-ink mb-8">Settings</h2>
{/* Network */}
<div className="card mb-6">
<div className="text-caption-strong text-muted uppercase tracking-wider mb-3">Network</div>
<div className="flex gap-2 p-1 bg-surface-soft rounded-pill">
{[{ id: 'devnet', l: 'Devnet' }, { id: 'mainnet-beta', l: 'Mainnet' }, { id: 'testnet', l: 'Testnet' }].map(n => (
<button key={n.id} onClick={() => setNetwork(n.id)} className={`flex-1 py-2 rounded-pill text-button transition-colors ${network === n.id ? 'bg-primary text-on-primary' : 'text-body hover:text-ink'}`}>{n.l}</button>
))}
</div>
<p className="text-caption text-muted mt-2">
{network === 'devnet' && 'Test tokens only. No real value.'}
{network === 'mainnet-beta' && 'Real tokens. Transactions irreversible.'}
{network === 'testnet' && 'Development purposes only.'}
</p>
</div>
{/* AI Models — Coinbase pricing-tier-card pattern */}
<div className="card mb-6">
<div className="flex items-center justify-between mb-4">
<div className="text-caption-strong text-muted uppercase tracking-wider">QVAC AI Models</div>
<span className="badge-pill text-[10px]">6 MODULES · ~2.6 GB</span>
</div>
<div className="space-y-0">
{models.map(m => (
<div key={m.name} className="flex items-center justify-between py-3 border-b border-hairline-soft last:border-0">
<div>
<div className="text-title-sm text-ink">{m.name}</div>
<div className="text-caption text-muted">{m.model}</div>
<div className="text-caption text-muted-soft font-mono">@qvac/{m.pkg}</div>
</div>
<div className="text-right">
<span className="badge-pill text-[10px] mr-2">{m.q}</span>
<span className="number-mono text-caption text-muted">{m.size}</span>
</div>
</div>
))}
</div>
<div className="hairline-soft mt-3 mb-3" />
<div className="text-caption text-muted flex items-center gap-1.5">
<div className="w-1.5 h-1.5 rounded-full bg-semantic-up" />
All models run locally via QVAC Fabric (Vulkan GPU) — no CUDA required
</div>
</div>
{/* About */}
<div className="card mb-6">
<div className="text-caption-strong text-muted uppercase tracking-wider mb-3">About</div>
<div className="text-body-sm text-body space-y-2">
<p><strong className="text-ink">SolVox</strong> — voice-first, privacy-preserving AI wallet for Solana.</p>
<p>Powered by <strong className="text-primary">Tether QVAC SDK</strong> — local AI that never phones home.</p>
</div>
<div className="flex flex-wrap gap-1.5 mt-3">
{['Electron', 'React', 'TypeScript', 'QVAC SDK', 'Solana', 'Vulkan'].map(t => (
<span key={t} className="badge-pill text-[10px]">{t}</span>
))}
</div>
<div className="hairline-soft my-3" />
<div className="text-caption text-muted-soft">Colosseum Frontier Hackathon · Tether QVAC Track</div>
</div>
{/* Lock */}
<div className="card border-semantic-down/20" style={{ borderColor: 'rgba(207, 32, 47, 0.15)' }}>
<div className="text-caption-strong text-semantic-down uppercase tracking-wider mb-3">Danger zone</div>
<button onClick={onLock} className="w-full py-3 rounded-pill border border-semantic-down/30 text-semantic-down text-button hover:bg-semantic-down/5 transition-colors">Lock wallet</button>
<p className="text-caption text-muted text-center mt-2">Zeroes private key from memory. PIN required to unlock.</p>
</div>
</div>
);
}