84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
|
|
import React from 'react';
|
||
|
|
|
||
|
|
interface ScanningToastProps {
|
||
|
|
isVisible: boolean;
|
||
|
|
message: string;
|
||
|
|
progress?: number; // 0-100 for progress bar
|
||
|
|
type?: 'scanning' | 'processing' | 'success' | 'error';
|
||
|
|
}
|
||
|
|
|
||
|
|
const ScanningToast: React.FC<ScanningToastProps> = ({
|
||
|
|
isVisible,
|
||
|
|
message,
|
||
|
|
progress,
|
||
|
|
type = 'scanning'
|
||
|
|
}) => {
|
||
|
|
if (!isVisible) return null;
|
||
|
|
|
||
|
|
const getTypeStyles = () => {
|
||
|
|
switch (type) {
|
||
|
|
case 'scanning':
|
||
|
|
return 'bg-blue-600 text-white';
|
||
|
|
case 'processing':
|
||
|
|
return 'bg-purple-600 text-white';
|
||
|
|
case 'success':
|
||
|
|
return 'bg-green-600 text-white';
|
||
|
|
case 'error':
|
||
|
|
return 'bg-red-600 text-white';
|
||
|
|
default:
|
||
|
|
return 'bg-blue-600 text-white';
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const getIcon = () => {
|
||
|
|
switch (type) {
|
||
|
|
case 'scanning':
|
||
|
|
return '📷';
|
||
|
|
case 'processing':
|
||
|
|
return '🤖';
|
||
|
|
case 'success':
|
||
|
|
return '✅';
|
||
|
|
case 'error':
|
||
|
|
return '❌';
|
||
|
|
default:
|
||
|
|
return '📷';
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 z-50 animate-slide-down">
|
||
|
|
<div className={`${getTypeStyles()} rounded-lg shadow-lg px-4 py-3 min-w-80 max-w-md`}>
|
||
|
|
<div className="flex items-center space-x-3">
|
||
|
|
{/* Icon */}
|
||
|
|
<div className="text-lg">{getIcon()}</div>
|
||
|
|
|
||
|
|
{/* Content */}
|
||
|
|
<div className="flex-1">
|
||
|
|
<div className="font-medium text-sm">{message}</div>
|
||
|
|
|
||
|
|
{/* Progress bar */}
|
||
|
|
{progress !== undefined && (
|
||
|
|
<div className="mt-2">
|
||
|
|
<div className="w-full bg-white/20 rounded-full h-1.5">
|
||
|
|
<div
|
||
|
|
className="bg-white h-1.5 rounded-full transition-all duration-300 ease-out"
|
||
|
|
style={{ width: `${Math.min(100, Math.max(0, progress))}%` }}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Spinner for scanning/processing */}
|
||
|
|
{(type === 'scanning' || type === 'processing') && (
|
||
|
|
<div className="w-5 h-5">
|
||
|
|
<div className="animate-spin rounded-full h-5 w-5 border-2 border-white border-t-transparent"></div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default ScanningToast;
|