Barazo default frontend barazo.forum
at main 63 lines 2.2 kB view raw
1/** 2 * Reusable error alert component for displaying API errors visibly. 3 * Used to replace silent error handling across admin and frontend pages. 4 */ 5 6'use client' 7 8import { WarningCircle, ArrowClockwise, X } from '@phosphor-icons/react' 9 10interface ErrorAlertProps { 11 /** Error message to display */ 12 message: string 13 /** Optional retry callback. Shows a retry button when provided. */ 14 onRetry?: () => void 15 /** Optional dismiss callback. Shows a dismiss button when provided. */ 16 onDismiss?: () => void 17 /** Visual variant: 'page' fills the content area, 'inline' sits alongside content */ 18 variant?: 'page' | 'inline' 19} 20 21export function ErrorAlert({ message, onRetry, onDismiss, variant = 'inline' }: ErrorAlertProps) { 22 if (variant === 'page') { 23 return ( 24 <div 25 role="alert" 26 className="flex flex-col items-center justify-center gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-6 py-12 text-center" 27 > 28 <WarningCircle size={32} className="text-destructive" aria-hidden="true" /> 29 <p className="text-sm text-destructive">{message}</p> 30 {onRetry && ( 31 <button 32 type="button" 33 onClick={onRetry} 34 className="mt-1 inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-sm text-foreground transition-colors hover:bg-muted" 35 > 36 <ArrowClockwise size={14} aria-hidden="true" /> 37 Retry 38 </button> 39 )} 40 </div> 41 ) 42 } 43 44 return ( 45 <div 46 role="alert" 47 className="flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2" 48 > 49 <WarningCircle size={16} className="shrink-0 text-destructive" aria-hidden="true" /> 50 <p className="flex-1 text-sm text-destructive">{message}</p> 51 {onDismiss && ( 52 <button 53 type="button" 54 onClick={onDismiss} 55 className="shrink-0 rounded-md p-1 text-destructive/60 transition-colors hover:text-destructive" 56 aria-label="Dismiss error" 57 > 58 <X size={14} aria-hidden="true" /> 59 </button> 60 )} 61 </div> 62 ) 63}