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 (
)
}
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 (
)
}