import { useState } from "react"; import { useDocker } from "../../hooks/useDocker"; import { useSettings } from "../../hooks/useSettings"; import type { ImageSource } from "../../lib/types"; const REGISTRY_IMAGE = "repo.anhonesthost.net/cybercovellc/triple-c/triple-c-sandbox:latest"; const IMAGE_SOURCE_OPTIONS: { value: ImageSource; label: string; description: string }[] = [ { value: "registry", label: "Registry", description: "Pull from container registry" }, { value: "local_build", label: "Local Build", description: "Build from embedded Dockerfile" }, { value: "custom", label: "Custom", description: "Specify a custom image" }, ]; export default function DockerSettings() { const { dockerAvailable, imageExists, checkDocker, checkImage, buildImage, pullImage } = useDocker(); const { appSettings, saveSettings } = useSettings(); const [working, setWorking] = useState(false); const [log, setLog] = useState([]); const [error, setError] = useState(null); const [customInput, setCustomInput] = useState(appSettings?.custom_image_name ?? ""); const imageSource = appSettings?.image_source ?? "registry"; const resolvedImageName = (() => { switch (imageSource) { case "registry": return REGISTRY_IMAGE; case "local_build": return "triple-c:latest"; case "custom": return customInput || REGISTRY_IMAGE; } })(); const handleSourceChange = async (source: ImageSource) => { if (!appSettings) return; await saveSettings({ ...appSettings, image_source: source }); await checkImage(); }; const handleCustomChange = async (value: string) => { setCustomInput(value); if (!appSettings) return; await saveSettings({ ...appSettings, custom_image_name: value || null }); }; const handlePull = async () => { setWorking(true); setLog([]); setError(null); try { await pullImage(resolvedImageName, (msg) => { setLog((prev) => [...prev, msg]); }); await checkImage(); } catch (e) { setError(String(e)); } finally { setWorking(false); } }; const handleBuild = async () => { setWorking(true); setLog([]); setError(null); try { await buildImage((msg) => { setLog((prev) => [...prev, msg]); }); await checkImage(); } catch (e) { setError(String(e)); } finally { setWorking(false); } }; return (
Docker Status {dockerAvailable === null ? "Checking..." : dockerAvailable ? "Connected" : "Not Available"}
{/* Image Source Selector */}
Image Source
{IMAGE_SOURCE_OPTIONS.map((opt) => ( ))}
{/* Custom image input */} {imageSource === "custom" && (
Custom Image handleCustomChange(e.target.value)} placeholder="e.g., myregistry.com/image:tag" className="w-full px-2 py-1.5 text-xs bg-[var(--bg-primary)] border border-[var(--border-color)] rounded focus:outline-none focus:border-[var(--accent)]" />
)} {/* Resolved image display */}
Image {resolvedImageName}
Status {imageExists === null ? "Checking..." : imageExists ? "Ready" : "Not Found"}
{/* Action buttons */}
{imageSource === "local_build" ? ( ) : ( )}
{/* Log output */} {log.length > 0 && (
{log.map((line, i) => (
{line}
))}
)} {error &&
{error}
}
); }