import { useEffect, useState } from 'react' import { apiRequest, changePassword, testEmail } from '../api/client' import { Save, Key, Mail } from 'lucide-react' interface PanelConfig { panel_port: number www_root: string setup_path: string webserver_type: string mysql_root_set: boolean app_name: string app_version: string } export function ConfigPage() { const [config, setConfig] = useState(null) const [configKeys, setConfigKeys] = useState>({}) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [saved, setSaved] = useState(false) const [pwSaved, setPwSaved] = useState(false) const [pwError, setPwError] = useState('') const [testEmailResult, setTestEmailResult] = useState(null) useEffect(() => { Promise.all([ apiRequest('/config/panel'), apiRequest>('/config/keys'), ]) .then(([cfg, keys]) => { setConfig(cfg) setConfigKeys(keys || {}) }) .catch((err) => setError(err.message)) .finally(() => setLoading(false)) }, []) const handleChangePassword = (e: React.FormEvent) => { e.preventDefault() setPwSaved(false) setPwError('') const form = e.currentTarget const oldPw = (form.elements.namedItem('old_password') as HTMLInputElement).value const newPw = (form.elements.namedItem('new_password') as HTMLInputElement).value const confirmPw = (form.elements.namedItem('confirm_password') as HTMLInputElement).value if (!oldPw || !newPw) { setPwError('All fields required') return } if (newPw !== confirmPw) { setPwError('New passwords do not match') return } if (newPw.length < 6) { setPwError('Password must be at least 6 characters') return } changePassword(oldPw, newPw) .then(() => { setPwSaved(true) form.reset() }) .catch((err) => setPwError(err.message)) } const handleTestEmail = () => { setTestEmailResult(null) testEmail() .then(() => setTestEmailResult('Test email sent!')) .catch((err) => setTestEmailResult(`Failed: ${err.message}`)) } const handleSave = (e: React.FormEvent) => { e.preventDefault() setSaved(false) const form = e.currentTarget const port = (form.elements.namedItem('panel_port') as HTMLInputElement).value const wwwRoot = (form.elements.namedItem('www_root') as HTMLInputElement).value const setupPath = (form.elements.namedItem('setup_path') as HTMLInputElement).value const webserver = (form.elements.namedItem('webserver_type') as HTMLSelectElement).value const mysqlRoot = (form.elements.namedItem('mysql_root') as HTMLInputElement).value const emailTo = (form.elements.namedItem('email_to') as HTMLInputElement)?.value || '' const smtpServer = (form.elements.namedItem('smtp_server') as HTMLInputElement)?.value || '' const smtpPort = (form.elements.namedItem('smtp_port') as HTMLInputElement)?.value || '587' const smtpUser = (form.elements.namedItem('smtp_user') as HTMLInputElement)?.value || '' const smtpPassword = (form.elements.namedItem('smtp_password') as HTMLInputElement)?.value || '' const promises: Promise[] = [ apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'panel_port', value: port }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'www_root', value: wwwRoot }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'setup_path', value: setupPath }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'webserver_type', value: webserver }) }), ] if (mysqlRoot) { promises.push(apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'mysql_root', value: mysqlRoot }) })) } promises.push( apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'email_to', value: emailTo }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'smtp_server', value: smtpServer }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'smtp_port', value: smtpPort }) }), apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'smtp_user', value: smtpUser }) }), ) if (smtpPassword) { promises.push(apiRequest('/config/set', { method: 'POST', body: JSON.stringify({ key: 'smtp_password', value: smtpPassword }) })) } Promise.all(promises) .then(() => setSaved(true)) .catch((err) => setError(err.message)) } if (loading) return
Loading...
if (error) return
{error}
if (!config) return null return (

Settings

Panel

Notifications (Email)

Used for panel alerts (e.g. backup completion, security warnings).

{testEmailResult && (

{testEmailResult}

)}

MySQL

Used to create/drop MySQL databases. Leave blank to keep current.

{saved && Saved}

Change Password

{pwError && (
{pwError}
)}
{pwSaved && Password changed}

App: {config.app_name} v{config.app_version}

Note: Some settings require a panel restart to take effect.

) }