import { useState, useEffect, useRef, useCallback } from "react"; import type { EnvVar } from "../../lib/types"; interface Props { envVars: EnvVar[]; disabled: boolean; onSave: (vars: EnvVar[]) => Promise; onClose: () => void; } export default function EnvVarsModal({ envVars: initial, disabled, onSave, onClose }: Props) { const [vars, setVars] = useState(initial); const overlayRef = useRef(null); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [onClose]); const handleOverlayClick = useCallback( (e: React.MouseEvent) => { if (e.target === overlayRef.current) onClose(); }, [onClose], ); const updateVar = (index: number, field: keyof EnvVar, value: string) => { const updated = [...vars]; updated[index] = { ...updated[index], [field]: value }; setVars(updated); }; const removeVar = async (index: number) => { const updated = vars.filter((_, i) => i !== index); setVars(updated); try { await onSave(updated); } catch (err) { console.error("Failed to remove environment variable:", err); } }; const addVar = async () => { const updated = [...vars, { key: "", value: "" }]; setVars(updated); try { await onSave(updated); } catch (err) { console.error("Failed to add environment variable:", err); } }; const handleBlur = async () => { try { await onSave(vars); } catch (err) { console.error("Failed to update environment variables:", err); } }; return (

Environment Variables

{disabled && (
Container must be stopped to change environment variables.
)}
{vars.length === 0 && (

No environment variables configured.

)} {vars.map((ev, i) => (
updateVar(i, "key", e.target.value)} onBlur={handleBlur} placeholder="KEY" disabled={disabled} className="w-2/5 px-2 py-1.5 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded text-sm text-[var(--text-primary)] focus:outline-none focus:border-[var(--accent)] disabled:opacity-50 font-mono" /> updateVar(i, "value", e.target.value)} onBlur={handleBlur} placeholder="value" disabled={disabled} className="flex-1 px-2 py-1.5 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded text-sm text-[var(--text-primary)] focus:outline-none focus:border-[var(--accent)] disabled:opacity-50 font-mono" />
))}
); }