File size: 3,804 Bytes
bfe0820 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | import React from "react";
import { motion } from "framer-motion";
import { AlertTriangle, RefreshCw, Hash } from "lucide-react";
import { Button } from "../ui/Button";
export function ErrorState({
title = "Analysis Encountered an Issue",
description = "We were unable to complete the analysis. Please check your network connection or try again.",
code,
requestId,
onRetry,
actionLabel = "Retry Analysis",
style = {},
}) {
return (
<motion.div
role="alert"
aria-live="assertive"
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
style={{
padding: "40px 28px",
textAlign: "center",
border: "1px solid var(--danger-border, rgba(239, 68, 68, 0.3))",
background: "linear-gradient(160deg, rgba(239,68,68,0.05) 0%, var(--bg-surface) 100%)",
borderRadius: "var(--radius-lg, 16px)",
maxWidth: "640px",
margin: "24px auto",
position: "relative",
overflow: "hidden",
...style,
}}
>
{/* Subtle danger radial glow */}
<div
aria-hidden="true"
style={{
position: "absolute",
inset: 0,
background:
"radial-gradient(ellipse 60% 40% at 50% 0%, rgba(239,68,68,0.06) 0%, transparent 70%)",
pointerEvents: "none",
}}
/>
<div
aria-hidden="true"
style={{
width: 60,
height: 60,
borderRadius: "50%",
background: "rgba(239, 68, 68, 0.12)",
border: "1px solid var(--danger-border, rgba(239, 68, 68, 0.4))",
display: "flex",
alignItems: "center",
justifyContent: "center",
margin: "0 auto 20px",
color: "var(--danger, #EF4444)",
position: "relative",
boxShadow: "0 0 0 8px rgba(239,68,68,0.04)",
}}
>
<AlertTriangle size={28} />
</div>
<h3
style={{
fontSize: "17px",
fontWeight: 700,
color: "var(--text-primary)",
marginBottom: "8px",
letterSpacing: "-0.01em",
lineHeight: 1.3,
}}
>
{title}
</h3>
<p
style={{
fontSize: "13.5px",
color: "var(--text-secondary)",
maxWidth: "460px",
margin: "0 auto 18px",
lineHeight: 1.6,
}}
>
{description}
</p>
{(code || requestId) && (
<div
style={{
display: "inline-flex",
alignItems: "center",
gap: "12px",
background: "var(--bg-surface)",
border: "1px solid var(--border)",
borderRadius: "var(--radius-md)",
padding: "6px 12px",
fontSize: "11px",
fontFamily: "var(--font-mono)",
color: "var(--text-muted)",
marginBottom: "20px",
flexWrap: "wrap",
justifyContent: "center",
}}
>
{code && (
<span>
Code: <strong style={{ color: "var(--text-primary)" }}>{code}</strong>
</span>
)}
{requestId && (
<span style={{ display: "flex", alignItems: "center", gap: "4px" }}>
<Hash size={12} color="var(--color-teal)" /> Request ID:{" "}
<strong style={{ color: "var(--color-teal)" }}>{requestId}</strong>
</span>
)}
</div>
)}
{onRetry && (
<div style={{ marginTop: "8px" }}>
<Button variant="primary" icon={RefreshCw} onClick={onRetry}>
{actionLabel}
</Button>
</div>
)}
</motion.div>
);
}
export default ErrorState;
|