"use client"; import { useState, useEffect, useRef } from "react"; import { X, User, Key, Tag, Cpu, Upload, Trash2, Loader2, CheckCircle2, AlertCircle } from "lucide-react"; import type { ManagedUser } from "@/lib/admin-api"; import { createAdminAgentUser, updateAdminAgentUser, deleteAdminAgentUser } from "@/lib/admin-api"; interface AgentAccountModalProps { isOpen: boolean; onClose: () => void; onSuccess: () => void; agentUuid: string; agentLabel: string; existingUser: ManagedUser | null; // null = create mode } export default function AgentAccountModal({ isOpen, onClose, onSuccess, agentUuid, agentLabel, existingUser, }: AgentAccountModalProps) { const isEdit = !!existingUser; const fileInputRef = useRef(null); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [accountName, setAccountName] = useState(""); const [previewPic, setPreviewPic] = useState(null); const [picFile, setPicFile] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const [success, setSuccess] = useState(""); const [error, setError] = useState(""); useEffect(() => { if (!isOpen) return; setError(""); setSuccess(""); setPicFile(null); if (existingUser) { setUsername(existingUser.username); setAccountName(existingUser.account_name || ""); setPassword(""); setPreviewPic( existingUser.profile_picture ? `/api/auth/uploads/${existingUser.profile_picture}` : null ); } else { setUsername(""); setAccountName(agentLabel !== agentUuid ? agentLabel : ""); setPassword(""); setPreviewPic(null); } }, [isOpen, existingUser, agentUuid, agentLabel]); const handlePicChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setPicFile(file); setPreviewPic(URL.createObjectURL(file)); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setSuccess(""); setIsSubmitting(true); try { if (isEdit) { const fd = new FormData(); fd.append("user_id", String(existingUser!.id)); if (username.trim()) fd.append("username", username.trim()); if (password) fd.append("password", password); fd.append("account_name", accountName.trim()); fd.append("agent_uuid", agentUuid); if (picFile) fd.append("profile_picture", picFile); await updateAdminAgentUser(fd); setSuccess("Account successfully updated!"); } else { await createAdminAgentUser({ username: username.trim(), password, account_name: accountName.trim() || undefined, agent_uuid: agentUuid, }); setSuccess("Network Agent account successfully created!"); } setTimeout(() => { onSuccess(); onClose(); }, 1200); } catch (err: any) { setError(err.message); } finally { setIsSubmitting(false); } }; const handleDelete = async () => { if (!existingUser) return; if (!confirm(`Delete account "${existingUser.username}"? This action cannot be undone.`)) return; setIsDeleting(true); try { await deleteAdminAgentUser(existingUser.id); onSuccess(); onClose(); } catch (err: any) { setError(err.message); } finally { setIsDeleting(false); } }; if (!isOpen) return null; return (
{/* Backdrop */}
{/* Modal */}
{/* Header */}

{isEdit ? "Edit Agent Account" : "Create New Agent Account"}

{agentUuid}

{/* Profile Picture */}
fileInputRef.current?.click()} > {previewPic ? ( Profile ) : ( )}

Profile Picture

Click to upload image

{/* Account Name (Label) */}
setAccountName(e.target.value)} placeholder="e.g., Gateway 007" className="w-full px-3 py-2.5 bg-slate-800 border border-slate-600 rounded-lg text-white placeholder-slate-500 text-sm focus:outline-none focus:border-blue-500 transition-colors" />

This name will appear as a label in the Agents tab

{/* Agent UUID (readonly info) */}
{/* Username */}
setUsername(e.target.value)} placeholder="Username for login" required={!isEdit} className="w-full px-3 py-2.5 bg-slate-800 border border-slate-600 rounded-lg text-white placeholder-slate-500 text-sm focus:outline-none focus:border-blue-500 transition-colors" />
{/* Password */}
setPassword(e.target.value)} placeholder={isEdit ? "••••••••" : "New password"} required={!isEdit} className="w-full px-3 py-2.5 bg-slate-800 border border-slate-600 rounded-lg text-white placeholder-slate-500 text-sm focus:outline-none focus:border-blue-500 transition-colors" />
{/* Feedback */} {error && (
{error}
)} {success && (
{success}
)} {/* Actions */}
{isEdit && ( )}
); }