Spaces:
Sleeping
Sleeping
| "use client" | |
| import { useState, useEffect } from "react" | |
| import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" | |
| import { Button } from "@/components/ui/button" | |
| import { Badge } from "@/components/ui/badge" | |
| import { Separator } from "@/components/ui/separator" | |
| import { | |
| ChevronDown, | |
| ChevronRight, | |
| Code2, | |
| Monitor, | |
| Cpu, | |
| HardDrive, | |
| Globe, | |
| Clock, | |
| Zap | |
| } from "lucide-react" | |
| interface DebugPanelProps { | |
| className?: string | |
| } | |
| export default function DebugPanel({ className }: DebugPanelProps) { | |
| const [isOpen, setIsOpen] = useState(false) | |
| const [systemInfo, setSystemInfo] = useState<any>({}) | |
| const [performanceMetrics, setPerformanceMetrics] = useState<any>({}) | |
| useEffect(() => { | |
| // Gather system information | |
| const info = { | |
| userAgent: navigator.userAgent, | |
| platform: navigator.platform, | |
| language: navigator.language, | |
| cookiesEnabled: navigator.cookieEnabled, | |
| onlineStatus: navigator.onLine, | |
| screenResolution: `${screen.width}x${screen.height}`, | |
| colorDepth: screen.colorDepth, | |
| timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, | |
| currentTime: new Date().toISOString(), | |
| buildTime: new Date().toISOString(), // In a real app, this would be from build | |
| version: "1.0.0", // From package.json in real app | |
| } | |
| setSystemInfo(info) | |
| // Performance metrics (mock data for demo) | |
| const metrics = { | |
| loadTime: Math.round(performance.now()), | |
| memoryUsage: (performance as any).memory ? { | |
| used: Math.round((performance as any).memory.usedJSHeapSize / 1024 / 1024), | |
| total: Math.round((performance as any).memory.totalJSHeapSize / 1024 / 1024), | |
| limit: Math.round((performance as any).memory.jsHeapSizeLimit / 1024 / 1024) | |
| } : null, | |
| connection: (navigator as any).connection ? { | |
| effectiveType: (navigator as any).connection.effectiveType, | |
| downlink: (navigator as any).connection.downlink, | |
| rtt: (navigator as any).connection.rtt | |
| } : null | |
| } | |
| setPerformanceMetrics(metrics) | |
| }, []) | |
| if (!isOpen) { | |
| return ( | |
| <div className={`fixed bottom-4 right-4 z-50 ${className}`}> | |
| <Button | |
| onClick={() => setIsOpen(true)} | |
| className="bg-purple-600 hover:bg-purple-700 text-white shadow-lg" | |
| size="sm" | |
| > | |
| <Code2 className="h-4 w-4 mr-1" /> | |
| Debug | |
| </Button> | |
| </div> | |
| ) | |
| } | |
| return ( | |
| <div className={`fixed bottom-4 right-4 z-50 w-96 ${className}`}> | |
| <Card className="bg-gray-900 text-white border-purple-500"> | |
| <CardHeader className="pb-3"> | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-2"> | |
| <Code2 className="h-5 w-5 text-purple-400" /> | |
| <CardTitle className="text-lg">Developer Debug Panel</CardTitle> | |
| </div> | |
| <Button | |
| variant="ghost" | |
| size="sm" | |
| onClick={() => setIsOpen(false)} | |
| className="text-gray-400 hover:text-white h-8 w-8 p-0" | |
| > | |
| × | |
| </Button> | |
| </div> | |
| <CardDescription className="text-gray-400"> | |
| System information and performance metrics | |
| </CardDescription> | |
| </CardHeader> | |
| <CardContent className="space-y-4 max-h-96 overflow-y-auto"> | |
| {/* System Info Section */} | |
| <div> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Monitor className="h-4 w-4 text-purple-400" /> | |
| <span className="font-medium">System Information</span> | |
| </div> | |
| <div className="space-y-2 text-sm"> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Platform:</span> | |
| <span>{systemInfo.platform}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Screen:</span> | |
| <span>{systemInfo.screenResolution}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Online:</span> | |
| <Badge variant={systemInfo.onlineStatus ? "default" : "destructive"} className="text-xs"> | |
| {systemInfo.onlineStatus ? "Connected" : "Offline"} | |
| </Badge> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Timezone:</span> | |
| <span className="text-right text-xs">{systemInfo.timezone}</span> | |
| </div> | |
| </div> | |
| </div> | |
| <Separator className="bg-gray-700" /> | |
| {/* Performance Section */} | |
| <div> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Zap className="h-4 w-4 text-purple-400" /> | |
| <span className="font-medium">Performance</span> | |
| </div> | |
| <div className="space-y-2 text-sm"> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Page Load:</span> | |
| <span>{performanceMetrics.loadTime}ms</span> | |
| </div> | |
| {performanceMetrics.memoryUsage && ( | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Memory:</span> | |
| <span>{performanceMetrics.memoryUsage.used}MB / {performanceMetrics.memoryUsage.total}MB</span> | |
| </div> | |
| )} | |
| {performanceMetrics.connection && ( | |
| <> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Connection:</span> | |
| <span>{performanceMetrics.connection.effectiveType}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">RTT:</span> | |
| <span>{performanceMetrics.connection.rtt}ms</span> | |
| </div> | |
| </> | |
| )} | |
| </div> | |
| </div> | |
| <Separator className="bg-gray-700" /> | |
| {/* App Info Section */} | |
| <div> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Globe className="h-4 w-4 text-purple-400" /> | |
| <span className="font-medium">Application</span> | |
| </div> | |
| <div className="space-y-2 text-sm"> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Version:</span> | |
| <span>{systemInfo.version}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Environment:</span> | |
| <Badge variant="outline" className="text-xs border-purple-400 text-purple-300"> | |
| Development | |
| </Badge> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-400">Framework:</span> | |
| <span>Next.js 15</span> | |
| </div> | |
| </div> | |
| </div> | |
| <Separator className="bg-gray-700" /> | |
| {/* Quick Actions */} | |
| <div> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Clock className="h-4 w-4 text-purple-400" /> | |
| <span className="font-medium">Quick Actions</span> | |
| </div> | |
| <div className="flex gap-2"> | |
| <Button | |
| variant="outline" | |
| size="sm" | |
| className="text-xs border-purple-400 text-purple-300 hover:bg-purple-800" | |
| onClick={() => window.location.reload()} | |
| > | |
| Reload | |
| </Button> | |
| <Button | |
| variant="outline" | |
| size="sm" | |
| className="text-xs border-purple-400 text-purple-300 hover:bg-purple-800" | |
| onClick={() => localStorage.clear()} | |
| > | |
| Clear Storage | |
| </Button> | |
| </div> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| </div> | |
| ) | |
| } |