"use client";
import { useState, useEffect } from "react";
import {
PROTOCOL_COLORS,
PROVIDER_COLORS,
getHttpStatusStyle as getStatusStyle,
} from "@/shared/constants/colors";
import { formatDuration, formatApiKeyLabel } from "@/shared/utils/formatting";
// ─── Payload Code Block ─────────────────────────────────────────────────────
function PayloadSection({ title, json, onCopy }) {
const [copied, setCopied] = useState(false);
const handleCopy = async () => {
const success = await onCopy();
if (success !== false) {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
};
return (
{title}
{json}
);
}
// ─── Detail Modal ───────────────────────────────────────────────────────────
export default function RequestLoggerDetail({ log, detail, loading, onClose, onCopy }) {
// Close on Escape key
useEffect(() => {
const handler = (e) => {
if (e.key === "Escape") onClose();
};
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [onClose]);
const statusStyle = getStatusStyle(log.status);
const protocolKey = log.sourceFormat || log.provider;
const protocol = PROTOCOL_COLORS[protocolKey] ||
PROTOCOL_COLORS[log.provider] || {
bg: "#6B7280",
text: "#fff",
label: (protocolKey || log.provider || "-").toUpperCase(),
};
const providerColor = PROVIDER_COLORS[log.provider] || {
bg: "#374151",
text: "#fff",
label: (log.provider || "-").toUpperCase(),
};
const formatDate = (iso) => {
try {
const d = new Date(iso);
return (
d.toLocaleDateString("pt-BR") + ", " + d.toLocaleTimeString("en-US", { hour12: false })
);
} catch {
return iso;
}
};
const requestJson = detail?.requestBody ? JSON.stringify(detail.requestBody, null, 2) : null;
const responseJson = detail?.responseBody ? JSON.stringify(detail.responseBody, null, 2) : null;
return (
e.stopPropagation()}
>
{/* Modal Header */}
{log.status}
{log.method}
{log.path}
{/* Metadata Grid */}
Time
{formatDate(log.timestamp)}
Duration
{formatDuration(log.duration)}
Tokens (I/O)
In: {(detail?.tokens?.in || log.tokens?.in || 0).toLocaleString()}
Out: {(detail?.tokens?.out || log.tokens?.out || 0).toLocaleString()}
Provider
{providerColor.label}
Protocol
{protocol.label}
Account
{detail?.account || log.account || "-"}
API Key
{formatApiKeyLabel(
detail?.apiKeyName || log.apiKeyName,
detail?.apiKeyId || log.apiKeyId
)}
Combo
{detail?.comboName || log.comboName ? (
{detail?.comboName || log.comboName}
) : (
—
)}
{/* Error Message */}
{(detail?.error || log.error) && (
Error
{detail?.error || log.error}
)}
{loading ? (
Loading request details...
) : (
<>
{/* Request Payload */}
{requestJson && (
onCopy(requestJson)}
/>
)}
{/* Response Payload */}
{responseJson && (
onCopy(responseJson)}
/>
)}
{!requestJson && !responseJson && !loading && (
info
No payload data available for this log entry.
Request/response bodies are only captured for non-streaming calls or when
streaming completes normally.
)}
>
)}
);
}