3 changed files with 95 additions and 0 deletions
@ -0,0 +1,70 @@ |
|||||
|
"use client"; |
||||
|
|
||||
|
import { useEffect, useState } from "react"; |
||||
|
|
||||
|
interface DebugLog { |
||||
|
id: string; |
||||
|
timestamp: string; |
||||
|
url: string; |
||||
|
method: string; |
||||
|
status: number; |
||||
|
headers: Record<string, string>; |
||||
|
response?: any; |
||||
|
} |
||||
|
|
||||
|
export default function DebugToast() { |
||||
|
const [logs, setLogs] = useState<DebugLog[]>([]); |
||||
|
const [isOpen, setIsOpen] = useState(false); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const handleDebugLog = (event: CustomEvent<DebugLog>) => { |
||||
|
setLogs((prev) => [event.detail, ...prev].slice(0, 10)); |
||||
|
setIsOpen(true); |
||||
|
}; |
||||
|
|
||||
|
window.addEventListener("debug-log" as any, handleDebugLog); |
||||
|
return () => window.removeEventListener("debug-log" as any, handleDebugLog); |
||||
|
}, []); |
||||
|
|
||||
|
if (!isOpen || logs.length === 0) return null; |
||||
|
|
||||
|
return ( |
||||
|
<div className="fixed top-4 right-4 z-[9999] max-w-md max-h-[80vh] overflow-auto bg-red-900 text-white p-4 rounded-lg shadow-2xl border-2 border-red-500"> |
||||
|
<div className="flex justify-between items-center mb-2"> |
||||
|
<h3 className="font-bold text-sm">🐛 Debug Log</h3> |
||||
|
<button |
||||
|
onClick={() => setIsOpen(false)} |
||||
|
className="text-white hover:text-red-200" |
||||
|
> |
||||
|
✕ |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
{logs.map((log) => ( |
||||
|
<div key={log.id} className="mb-4 p-2 bg-red-950 rounded text-xs"> |
||||
|
<div className="font-bold mb-1"> |
||||
|
{log.method} {log.status} |
||||
|
</div> |
||||
|
<div className="mb-1 text-red-300 break-all">{log.url}</div> |
||||
|
<div className="mb-1 text-yellow-300">{log.timestamp}</div> |
||||
|
|
||||
|
<details className="mt-2"> |
||||
|
<summary className="cursor-pointer text-blue-300">Headers</summary> |
||||
|
<pre className="mt-1 text-[10px] overflow-auto"> |
||||
|
{JSON.stringify(log.headers, null, 2)} |
||||
|
</pre> |
||||
|
</details> |
||||
|
|
||||
|
{log.response && ( |
||||
|
<details className="mt-2"> |
||||
|
<summary className="cursor-pointer text-blue-300">Response</summary> |
||||
|
<pre className="mt-1 text-[10px] overflow-auto"> |
||||
|
{JSON.stringify(log.response, null, 2)} |
||||
|
</pre> |
||||
|
</details> |
||||
|
)} |
||||
|
</div> |
||||
|
))} |
||||
|
</div> |
||||
|
); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue