| "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(() => { |
| |
| 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(), |
| version: "1.0.0", |
| } |
| setSystemInfo(info) |
|
|
| |
| 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> |
| ) |
| } |