Add src/components/AddHostModal.tsx

This commit is contained in:
Zac Gaetano 2026-03-31 15:29:59 -04:00
parent 69c7f281c0
commit 7a6fdde3ed

View file

@ -0,0 +1,81 @@
import { useState } from "react";
import { api } from "../api";
interface Props {
onClose: () => void;
onAdded: () => void;
}
export function AddHostModal({ onClose, onAdded }: Props) {
const [name, setName] = useState("");
const [ip, setIp] = useState("");
const [port, setPort] = useState("47984");
const [error, setError] = useState<string | null>(null);
const [saving, setSaving] = useState(false);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setSaving(true);
setError(null);
try {
await api.addManualHost(name, ip, parseInt(port, 10) || 47984);
onAdded();
onClose();
} catch (err: unknown) {
setError(err instanceof Error ? err.message : "Failed to add host");
} finally {
setSaving(false);
}
}
return (
<div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={onClose}>
<div
className="bg-surface-raised border border-surface-elevated rounded-2xl p-6 w-80 shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<h2 className="text-lg font-semibold mb-4">Add Host Manually</h2>
<form onSubmit={handleSubmit} className="flex flex-col gap-3">
<input
className="bg-surface-elevated rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-accent"
placeholder="Display name"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
<input
className="bg-surface-elevated rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-accent"
placeholder="IP or Tailscale hostname"
value={ip}
onChange={(e) => setIp(e.target.value)}
required
/>
<input
className="bg-surface-elevated rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-accent"
placeholder="Port (default 47984)"
value={port}
onChange={(e) => setPort(e.target.value)}
type="number"
/>
{error && <p className="text-xs text-red-400">{error}</p>}
<div className="flex gap-2 mt-2">
<button
type="button"
onClick={onClose}
className="flex-1 py-2 rounded-lg bg-surface-elevated text-sm"
>
Cancel
</button>
<button
type="submit"
disabled={saving}
className="flex-1 py-2 rounded-lg bg-accent text-sm font-medium disabled:opacity-50"
>
{saving ? "Adding…" : "Add"}
</button>
</div>
</form>
</div>
</div>
);
}