"use client" import { useCallback, useEffect, useState } from "react" import { Check, Copy, Eye, EyeOff } from "lucide-react" import { startWebServer, stopWebServer, getWebServerStatus, type WebServerInfo, } from "@/lib/api" function CopyableCard({ label, value, masked, }: { label: string value: string masked?: boolean }) { const [hovered, setHovered] = useState(false) const [copied, setCopied] = useState(false) const [revealed, setRevealed] = useState(false) function handleCopy() { navigator.clipboard.writeText(value) setCopied(true) setTimeout(() => setCopied(false), 1500) } const displayValue = masked && !revealed ? value.slice(0, 4) + "\u2022".repeat(Math.max(value.length - 4, 8)) : value return (
{label}
setHovered(true)} onMouseLeave={() => setHovered(false)} > {displayValue}
{masked && ( )}
) } export function WebServiceSettings() { const [status, setStatus] = useState(null) const [port, setPort] = useState("3080") const [loading, setLoading] = useState(false) const [error, setError] = useState("") const fetchStatus = useCallback(async () => { try { const info = await getWebServerStatus() setStatus(info) if (info) { setPort(String(info.port)) } } catch { // Server status unavailable } }, []) useEffect(() => { fetchStatus() }, [fetchStatus]) async function handleStart() { setError("") setLoading(true) try { const info = await startWebServer({ port: parseInt(port, 10) || 3080, }) setStatus(info) } catch (e: unknown) { const msg = e && typeof e === "object" && "message" in e ? (e as { message: string }).message : "启动失败" setError(msg) } finally { setLoading(false) } } async function handleStop() { setLoading(true) try { await stopWebServer() setStatus(null) } catch { setError("停止失败") } finally { setLoading(false) } } const isRunning = status !== null return (

Web 服务

启用后可通过浏览器远程访问 Codeg

{/* Port config */}
setPort(e.target.value)} disabled={isRunning} min={1024} max={65535} className="flex h-9 w-32 rounded-md border border-input bg-background px-3 py-1 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50" />
{/* Start/Stop button */}
{isRunning ? "运行中" : "已停止"}
{error && (

{error}

)} {/* Connection info */} {isRunning && (
{status.addresses.map((addr) => ( ))}

Web 客户端首次访问时需输入此 Token

)}
) }