File size: 4,763 Bytes
945e815 5f5514e 945e815 5f5514e 945e815 5f5514e 383d246 945e815 5f5514e 945e815 5f5514e 945e815 5f5514e 945e815 5f5514e 383d246 5f5514e 383d246 5f5514e 383d246 5f5514e 945e815 5f5514e 383d246 945e815 5f5514e 945e815 5f5514e 945e815 5f5514e 945e815 5f5514e 945e815 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 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>
);
}
|