Spaces:
Sleeping
Sleeping
| import { Brain } from 'lucide-react' | |
| interface Props { | |
| title?: string | |
| subtitle?: string | |
| statusText?: string | |
| } | |
| export default function LoadingState({ | |
| title = "Đang phân tích hình ảnh MRI", | |
| subtitle = "Hệ thống đang thực hiện gọt sọ, trích xuất đặc trưng hình ảnh và tính toán xác suất bệnh lý. Vui lòng chờ trong giây lát...", | |
| statusText = "Hệ thống đang xử lý" | |
| }: Props) { | |
| return ( | |
| <div className="flex min-h-[60vh] flex-col items-center justify-center gap-10 px-4 py-16"> | |
| {/* CSS Hoạt họa cục bộ để tạo hiệu ứng trượt vô hạn và sóng radar đồng tâm */} | |
| <style>{` | |
| @keyframes radar-ripple { | |
| 0% { | |
| transform: scale(0.95); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: scale(2.2); | |
| opacity: 0; | |
| } | |
| } | |
| @keyframes loading-slide { | |
| 0% { | |
| transform: translateX(-100%); | |
| } | |
| 100% { | |
| transform: translateX(200%); | |
| } | |
| } | |
| .animate-radar-ripple-1 { | |
| animation: radar-ripple 3s cubic-bezier(0, 0, 0.2, 1) infinite; | |
| } | |
| .animate-radar-ripple-2 { | |
| animation: radar-ripple 3s cubic-bezier(0, 0, 0.2, 1) infinite; | |
| animation-delay: 1s; | |
| } | |
| .animate-radar-ripple-3 { | |
| animation: radar-ripple 3s cubic-bezier(0, 0, 0.2, 1) infinite; | |
| animation-delay: 2s; | |
| } | |
| .animate-loading-slide { | |
| animation: loading-slide 2s cubic-bezier(0.4, 0, 0.2, 1) infinite; | |
| } | |
| `}</style> | |
| {/* Radar Pulse Animation & Brain Icon */} | |
| <div className="relative flex h-36 w-36 items-center justify-center"> | |
| {/* Các vòng sóng radar đồng tâm phát sáng ngọc bích */} | |
| <div className="absolute h-16 w-16 rounded-full bg-teal-500/20 opacity-0 animate-radar-ripple-1" /> | |
| <div className="absolute h-16 w-16 rounded-full bg-teal-500/15 opacity-0 animate-radar-ripple-2" /> | |
| <div className="absolute h-16 w-16 rounded-full bg-teal-500/10 opacity-0 animate-radar-ripple-3" /> | |
| {/* Vòng viền xoay nhẹ tĩnh phía trong */} | |
| <div className="absolute h-20 w-20 animate-[spin_10s_linear_infinite] rounded-full border border-dashed border-teal-300/40" /> | |
| {/* Vòng tròn trung tâm chứa biểu tượng bộ não */} | |
| <div className="relative z-10 flex h-20 w-20 animate-pulse items-center justify-center rounded-full bg-gradient-to-tr from-teal-500 to-emerald-500 shadow-lg shadow-teal-500/30"> | |
| <Brain className="h-10 w-10 text-white" strokeWidth={1.5} /> | |
| </div> | |
| </div> | |
| {/* Text thuyết minh trạng thái sang trọng */} | |
| <div className="flex flex-col items-center gap-3 text-center max-w-sm"> | |
| <h3 className="text-lg font-bold text-slate-800 tracking-tight"> | |
| {title} | |
| </h3> | |
| <p className="text-sm text-slate-500 leading-relaxed font-normal"> | |
| {subtitle} | |
| </p> | |
| </div> | |
| {/* Thanh loading trượt vô hạn cực mảnh */} | |
| <div className="w-full max-w-xs space-y-2"> | |
| <div className="relative h-1 w-full overflow-hidden rounded-full bg-slate-100"> | |
| <div className="absolute top-0 bottom-0 left-0 w-1/3 rounded-full bg-gradient-to-r from-teal-500 to-emerald-500 animate-loading-slide" /> | |
| </div> | |
| <p className="text-center text-[11px] font-medium uppercase tracking-widest text-teal-600/80 animate-pulse"> | |
| {statusText} | |
| </p> | |
| </div> | |
| </div> | |
| ) | |
| } | |