import { AnimatePresence, motion } from 'framer-motion'; import type { ActionAlert } from '~/types/actions'; import { classNames } from '~/utils/classNames'; interface Props { alert: ActionAlert; clearAlert: () => void; postMessage: (message: string) => void; } export default function ChatAlert({ alert, clearAlert, postMessage }: Props) { const { description, content, source } = alert; const isPreview = source === 'preview'; const title = isPreview ? 'Preview Error' : 'Terminal Error'; const message = isPreview ? 'We encountered an error while running the preview. Would you like Bolt to analyze and help resolve this issue?' : 'We encountered an error while running terminal commands. Would you like Bolt to analyze and help resolve this issue?'; return ( <AnimatePresence> <motion.div initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.3 }} className={`rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-background-depth-2 p-4 mb-2`} > <div className="flex items-start"> {/* Icon */} <motion.div className="flex-shrink-0" initial={{ scale: 0 }} animate={{ scale: 1 }} transition={{ delay: 0.2 }} > <div className={`i-ph:warning-duotone text-xl text-bolt-elements-button-danger-text`}></div> </motion.div> {/* Content */} <div className="ml-3 flex-1"> <motion.h3 initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.1 }} className={`text-sm font-medium text-bolt-elements-textPrimary`} > {title} </motion.h3> <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.2 }} className={`mt-2 text-sm text-bolt-elements-textSecondary`} > <p>{message}</p> {description && ( <div className="text-xs text-bolt-elements-textSecondary p-2 bg-bolt-elements-background-depth-3 rounded mt-4 mb-4"> Error: {description} </div> )} </motion.div> {/* Actions */} <motion.div className="mt-4" initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.3 }} > <div className={classNames(' flex gap-2')}> <button onClick={() => postMessage( `*Fix this ${isPreview ? 'preview' : 'terminal'} error* \n\`\`\`${isPreview ? 'js' : 'sh'}\n${content}\n\`\`\`\n`, ) } className={classNames( `px-2 py-1.5 rounded-md text-sm font-medium`, 'bg-bolt-elements-button-primary-background', 'hover:bg-bolt-elements-button-primary-backgroundHover', 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bolt-elements-button-danger-background', 'text-bolt-elements-button-primary-text', 'flex items-center gap-1.5', )} > <div className="i-ph:chat-circle-duotone"></div> Ask Bolt </button> <button onClick={clearAlert} className={classNames( `px-2 py-1.5 rounded-md text-sm font-medium`, 'bg-bolt-elements-button-secondary-background', 'hover:bg-bolt-elements-button-secondary-backgroundHover', 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bolt-elements-button-secondary-background', 'text-bolt-elements-button-secondary-text', )} > Dismiss </button> </div> </motion.div> </div> </div> </motion.div> </AnimatePresence> ); }