import { useState } from 'react' import { Server, Container, Network, Cloud, CloudCog, Activity, CloudSun, Check, ArrowRight } from 'lucide-react' import { useAuth } from '../lib/AuthContext' import { api, ApiError } from '../lib/api' const cardBase: React.CSSProperties = { backgroundColor: 'rgba(10, 10, 12, 0.92)', border: '1px solid rgba(200, 164, 52, 0.12)', borderRadius: '14px', padding: '32px', } const fieldLabel: React.CSSProperties = { fontSize: '11px', color: '#7A7D85', marginBottom: '6px', display: 'block', } const fieldInput: React.CSSProperties = { width: '100%', height: '36px', borderRadius: '8px', border: '1px solid rgba(200,164,52,0.12)', backgroundColor: 'rgba(255,255,255,0.03)', color: '#E8E6E0', fontSize: '13px', padding: '0 12px', outline: 'none', } const goldButton: React.CSSProperties = { height: '38px', borderRadius: '8px', border: 'none', fontSize: '13px', fontWeight: 600, color: '#0A0B0D', backgroundColor: '#C8A434', boxShadow: '0 0 14px rgba(200,164,52,0.2)', padding: '0 20px', } const integrationOptions = [ { type: 'proxmox', name: 'Proxmox', icon: Server }, { type: 'docker', name: 'Docker', icon: Container }, { type: 'netbird', name: 'NetBird', icon: Network }, { type: 'cloudflare', name: 'Cloudflare', icon: Cloud }, { type: 'aws', name: 'AWS', icon: CloudCog }, { type: 'uptime_kuma', name: 'Uptime Kuma', icon: Activity }, { type: 'weather', name: 'Weather API', icon: CloudSun }, ] as const export default function Enrollment() { const { status, completeSetup, finishEnrollment } = useAuth() const step = status === 'enrolling' ? 'connect' : 'account' return (
{step === 'account' ? ( ) : ( )}
) } function AccountStep({ completeSetup, }: { completeSetup: (username: string, password: string) => Promise }) { const [username, setUsername] = useState('') const [password, setPassword] = useState('') const [confirm, setConfirm] = useState('') const [error, setError] = useState(null) const [submitting, setSubmitting] = useState(false) async function handleSubmit(e: React.FormEvent) { e.preventDefault() setError(null) if (password !== confirm) { setError('Passwords do not match') return } if (password.length < 8) { setError('Password must be at least 8 characters') return } setSubmitting(true) try { await completeSetup(username, password) } catch (err) { setError(err instanceof ApiError ? err.message : 'Setup failed') } finally { setSubmitting(false) } } return (

Welcome to ArchNest

Create your admin account to get started

setUsername(e.target.value)} autoFocus required /> setPassword(e.target.value)} required /> setConfirm(e.target.value)} required /> {error &&

{error}

}
) } function ConnectStep({ onFinish }: { onFinish: () => Promise }) { const [connected, setConnected] = useState>(new Set()) const [active, setActive] = useState<(typeof integrationOptions)[number] | null>(null) return (

Connect Your Services

Add the integrations you want ArchNest to monitor. You can also do this later from Settings.

{active ? ( { setConnected((prev) => new Set(prev).add(active.type)) setActive(null) }} onCancel={() => setActive(null)} /> ) : (
{integrationOptions.map((opt) => { const Icon = opt.icon const isDone = connected.has(opt.type) return ( ) })}
)} {!active && (
)}
) } function ConnectForm({ option, onConnected, onCancel, }: { option: (typeof integrationOptions)[number] onConnected: () => void onCancel: () => void }) { const [baseUrl, setBaseUrl] = useState('') const [apiKey, setApiKey] = useState('') const [error, setError] = useState(null) const [testResult, setTestResult] = useState(null) const [submitting, setSubmitting] = useState(false) async function handleSubmit(e: React.FormEvent) { e.preventDefault() setError(null) setTestResult(null) setSubmitting(true) try { const { integration } = await api.createIntegration({ type: option.type, name: option.name, config: baseUrl ? { baseUrl } : {}, secrets: apiKey ? { apiKey } : {}, }) const result = await api.testIntegration(integration.id) setTestResult(result.message) if (result.ok) onConnected() } catch (err) { setError(err instanceof ApiError ? err.message : 'Failed to add integration') } finally { setSubmitting(false) } } return (

{option.name}

setBaseUrl(e.target.value)} placeholder="https://..." /> setApiKey(e.target.value)} /> {error &&

{error}

} {testResult &&

{testResult}

}
) }