website refactor
This commit is contained in:
107
apps/website/components/errors/ErrorDetailsBlock.tsx
Normal file
107
apps/website/components/errors/ErrorDetailsBlock.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Copy, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
|
||||
interface ErrorDetailsBlockProps {
|
||||
error: Error & { digest?: string };
|
||||
}
|
||||
|
||||
/**
|
||||
* ErrorDetailsBlock
|
||||
*
|
||||
* Semantic component for technical error details.
|
||||
* Follows "Precision Racing Minimal" theme.
|
||||
*/
|
||||
export function ErrorDetailsBlock({ error }: ErrorDetailsBlockProps) {
|
||||
const [showDetails, setShowDetails] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const copyError = async () => {
|
||||
const details = {
|
||||
message: error.message,
|
||||
digest: error.digest,
|
||||
stack: error.stack,
|
||||
url: typeof window !== 'undefined' ? window.location.href : 'unknown',
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(JSON.stringify(details, null, 2));
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
} catch (err) {
|
||||
// Silent fail
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap={4} fullWidth pt={4} borderTop borderColor="border-white" bgOpacity={0.1}>
|
||||
<Box
|
||||
as="button"
|
||||
onClick={() => setShowDetails(!showDetails)}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap={2}
|
||||
transition
|
||||
>
|
||||
<Text
|
||||
size="xs"
|
||||
color="text-gray-500"
|
||||
hoverTextColor="text-gray-300"
|
||||
uppercase
|
||||
letterSpacing="widest"
|
||||
weight="medium"
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
{showDetails ? <Icon icon={ChevronUp} size={3} /> : <Icon icon={ChevronDown} size={3} />}
|
||||
{showDetails ? 'Hide Technical Logs' : 'Show Technical Logs'}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
{showDetails && (
|
||||
<Stack gap={3}>
|
||||
<Surface
|
||||
variant="dark"
|
||||
rounded="md"
|
||||
padding={4}
|
||||
fullWidth
|
||||
maxHeight="48"
|
||||
overflow="auto"
|
||||
border
|
||||
borderColor="border-white"
|
||||
bgOpacity={0.4}
|
||||
hideScrollbar={false}
|
||||
>
|
||||
<Text font="mono" size="xs" color="text-gray-500" block leading="relaxed">
|
||||
{error.stack || 'No stack trace available'}
|
||||
{error.digest && `\n\nDigest: ${error.digest}`}
|
||||
</Text>
|
||||
</Surface>
|
||||
|
||||
<Box display="flex" justifyContent="end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={copyError}
|
||||
icon={<Icon icon={Copy} size={3} />}
|
||||
height="8"
|
||||
fontSize="10px"
|
||||
>
|
||||
{copied ? 'Copied to Clipboard' : 'Copy Error Details'}
|
||||
</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user