Dev console

This commit is contained in:
Jack Mechem 2026-05-21 19:18:44 -07:00
parent 876da0c384
commit 0d75cb5913

View file

@ -32,12 +32,12 @@ function tryPretty(text: string): string {
function methodBg(method: string): string {
switch (method) {
case "GET": return "#1d4ed8";
case "POST": return "#15803d";
case "PUT": return "#b45309";
case "PATCH": return "#6d28d9";
case "DELETE": return "#b91c1c";
default: return "#475569";
case "GET": return "#2563eb";
case "POST": return "#16a34a";
case "PUT": return "#d97706";
case "PATCH": return "#7c3aed";
case "DELETE": return "#dc2626";
default: return "#6b7280";
}
}
@ -124,8 +124,9 @@ export default function DevConsole({
zIndex: 50,
display: "flex",
flexDirection: "column",
background: "#0f172a",
borderLeft: "1px solid #1e293b",
background: "#ffffff",
borderLeft: "1px solid #e5e7eb",
boxShadow: "-4px 0 24px rgba(0,0,0,0.06)",
transform: open ? "translateX(0)" : "translateX(100%)",
transition: "transform 280ms cubic-bezier(0.4,0,0.2,1)",
}}
@ -157,16 +158,17 @@ export default function DevConsole({
alignItems: "center",
gap: "8px",
padding: "10px 14px",
borderBottom: "1px solid #1e293b",
borderBottom: "1px solid #e5e7eb",
flexShrink: 0,
background: "#ffffff",
}}>
<LuTerminal size={13} style={{ color: "#475569" }} />
<LuTerminal size={13} style={{ color: "#9ca3af" }} />
<span style={{
fontSize: "0.65rem",
fontWeight: 700,
letterSpacing: "0.1em",
textTransform: "uppercase",
color: "#475569",
color: "#9ca3af",
}}>
Dev Console
</span>
@ -180,11 +182,11 @@ export default function DevConsole({
fontSize: "0.68rem",
fontWeight: 500,
padding: "3px 9px",
borderRadius: "4px",
borderRadius: "6px",
border: "none",
cursor: "pointer",
background: activeTab === tab ? "#1e293b" : "transparent",
color: activeTab === tab ? "#e2e8f0" : "#475569",
background: activeTab === tab ? "#f3f4f6" : "transparent",
color: activeTab === tab ? "#111827" : "#9ca3af",
textTransform: "capitalize",
}}
>
@ -198,7 +200,7 @@ export default function DevConsole({
background: "transparent",
border: "none",
cursor: "pointer",
color: "#475569",
color: "#9ca3af",
display: "flex",
alignItems: "center",
padding: "2px",
@ -213,7 +215,7 @@ export default function DevConsole({
{activeTab === "logs" && (
<div style={{ flex: 1, overflowY: "auto", fontFamily: "ui-monospace, 'Cascadia Code', monospace" }}>
{logs.length === 0 ? (
<div style={{ padding: "32px 16px", textAlign: "center", color: "#1e293b", fontSize: "0.75rem" }}>
<div style={{ padding: "32px 16px", textAlign: "center", color: "#d1d5db", fontSize: "0.75rem" }}>
No requests captured yet
</div>
) : (
@ -232,16 +234,16 @@ export default function DevConsole({
{/* Request tab */}
{activeTab === "request" && (
<div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
<div style={{ padding: "12px", borderBottom: "1px solid #1e293b", flexShrink: 0 }}>
<div style={{ padding: "12px", borderBottom: "1px solid #e5e7eb", flexShrink: 0 }}>
<div style={{ display: "flex", gap: "6px", marginBottom: "8px" }}>
<select
value={reqMethod}
onChange={(e) => setReqMethod(e.target.value)}
style={{
background: "#1e293b",
border: "1px solid #334155",
borderRadius: "6px",
color: "#e2e8f0",
background: "#f9fafb",
border: "1px solid #e5e7eb",
borderRadius: "8px",
color: "#111827",
fontSize: "0.68rem",
padding: "5px 6px",
cursor: "pointer",
@ -260,10 +262,10 @@ export default function DevConsole({
placeholder="/api/power"
style={{
flex: 1,
background: "#1e293b",
border: "1px solid #334155",
borderRadius: "6px",
color: "#e2e8f0",
background: "#f9fafb",
border: "1px solid #e5e7eb",
borderRadius: "8px",
color: "#111827",
fontSize: "0.68rem",
padding: "5px 8px",
fontFamily: "ui-monospace, monospace",
@ -277,7 +279,7 @@ export default function DevConsole({
style={{
background: "#2563eb",
border: "none",
borderRadius: "6px",
borderRadius: "8px",
color: "white",
padding: "5px 11px",
cursor: reqLoading ? "default" : "pointer",
@ -303,10 +305,10 @@ export default function DevConsole({
rows={4}
style={{
width: "100%",
background: "#1e293b",
border: "1px solid #334155",
borderRadius: "6px",
color: "#e2e8f0",
background: "#f9fafb",
border: "1px solid #e5e7eb",
borderRadius: "8px",
color: "#111827",
fontSize: "0.68rem",
padding: "6px 8px",
fontFamily: "ui-monospace, monospace",
@ -318,11 +320,11 @@ export default function DevConsole({
/>
)}
<div style={{ fontSize: "0.6rem", color: "#334155" }}>
<div style={{ fontSize: "0.6rem", color: "#d1d5db" }}>
Bearer token attached via cookie ·{" "}
<span style={{ color: "#3b4a5e" }}>use</span>{" "}
<code style={{ color: "#475569" }}>http://localhost:3001/path</code>{" "}
<span style={{ color: "#3b4a5e" }}>to bypass Next.js proxy</span>
<span style={{ color: "#9ca3af" }}>use</span>{" "}
<code style={{ color: "#6b7280" }}>http://localhost:3001/path</code>{" "}
<span style={{ color: "#9ca3af" }}>to bypass Next.js proxy</span>
</div>
</div>
@ -331,9 +333,10 @@ export default function DevConsole({
overflow: "auto",
padding: "12px",
fontFamily: "ui-monospace, 'Cascadia Code', monospace",
background: "#f9fafb",
}}>
{reqLoading && (
<div style={{ fontSize: "0.7rem", color: "#475569" }}>Sending</div>
<div style={{ fontSize: "0.7rem", color: "#9ca3af" }}>Sending</div>
)}
{!reqLoading && reqResponse && (
<>
@ -341,13 +344,13 @@ export default function DevConsole({
fontSize: "0.65rem",
fontWeight: 600,
marginBottom: "8px",
color: reqResponse.status >= 200 && reqResponse.status < 300 ? "#34d399" : "#f87171",
color: reqResponse.status >= 200 && reqResponse.status < 300 ? "#16a34a" : "#dc2626",
}}>
HTTP {reqResponse.status}
</div>
<pre style={{
fontSize: "0.65rem",
color: "#94a3b8",
color: "#6b7280",
margin: 0,
whiteSpace: "pre-wrap",
wordBreak: "break-all",
@ -358,7 +361,7 @@ export default function DevConsole({
</>
)}
{!reqLoading && !reqResponse && (
<div style={{ fontSize: "0.7rem", color: "#1e293b" }}>
<div style={{ fontSize: "0.7rem", color: "#d1d5db" }}>
Response will appear here
</div>
)}
@ -381,13 +384,13 @@ function LogRow({
const [hovered, setHovered] = useState(false);
const statusColor =
entry.status === null
? "#475569"
? "#9ca3af"
: entry.status >= 200 && entry.status < 300
? "#34d399"
: "#f87171";
? "#16a34a"
: "#dc2626";
return (
<div style={{ borderBottom: "1px solid #0f1a2a" }}>
<div style={{ borderBottom: "1px solid #f3f4f6" }}>
<div
onClick={onToggle}
onMouseEnter={() => setHovered(true)}
@ -398,14 +401,14 @@ function LogRow({
gap: "8px",
padding: "6px 12px",
cursor: "pointer",
background: hovered ? "#1a2540" : "transparent",
background: hovered ? "#f9fafb" : "transparent",
}}
>
<span style={{
fontSize: "0.58rem",
fontWeight: 700,
padding: "1px 5px",
borderRadius: "3px",
borderRadius: "4px",
minWidth: "38px",
textAlign: "center",
background: methodBg(entry.method),
@ -427,7 +430,7 @@ function LogRow({
</span>
<span style={{
fontSize: "0.68rem",
color: "#94a3b8",
color: "#6b7280",
flex: 1,
overflow: "hidden",
textOverflow: "ellipsis",
@ -435,23 +438,23 @@ function LogRow({
}}>
{entry.path}
</span>
<span style={{ fontSize: "0.6rem", color: "#334155", flexShrink: 0 }}>
<span style={{ fontSize: "0.6rem", color: "#9ca3af", flexShrink: 0 }}>
{entry.duration !== null ? `${entry.duration}ms` : ""}
</span>
<span style={{ fontSize: "0.6rem", color: "#1e293b", flexShrink: 0 }}>
<span style={{ fontSize: "0.6rem", color: "#d1d5db", flexShrink: 0 }}>
{entry.timestamp}
</span>
</div>
{expanded && (
<div style={{
background: "#080d18",
background: "#f9fafb",
padding: "8px 12px 10px",
borderTop: "1px solid #1e293b",
borderTop: "1px solid #e5e7eb",
}}>
<div style={{
fontSize: "0.6rem",
color: "#334155",
color: "#9ca3af",
marginBottom: "6px",
wordBreak: "break-all",
}}>
@ -460,7 +463,7 @@ function LogRow({
{entry.response !== null && (
<pre style={{
fontSize: "0.63rem",
color: "#94a3b8",
color: "#6b7280",
margin: 0,
overflow: "auto",
maxHeight: "220px",