Files
igny8/site-builder/src/components/common/ProgressModal.tsx
2025-11-18 06:36:56 +05:00

77 lines
2.1 KiB
TypeScript

import { useEffect } from 'react';
import { X, Loader2 } from 'lucide-react';
import './ProgressModal.css';
interface ProgressModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
message?: string;
progress?: {
current: number;
total: number;
};
taskId?: string;
}
export function ProgressModal({ isOpen, onClose, title, message, progress, taskId }: ProgressModalProps) {
useEffect(() => {
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
return () => {
document.body.style.overflow = '';
};
}, [isOpen]);
if (!isOpen) return null;
const progressPercent = progress ? Math.round((progress.current / progress.total) * 100) : 0;
return (
<div className="progress-modal-overlay" onClick={onClose}>
<div className="progress-modal" onClick={(e) => e.stopPropagation()}>
<div className="progress-modal-header">
<h3>{title}</h3>
<button type="button" className="progress-modal-close" onClick={onClose} aria-label="Close">
<X size={20} />
</button>
</div>
<div className="progress-modal-content">
{message && <p className="progress-modal-message">{message}</p>}
{progress && (
<div className="progress-modal-bar">
<div className="progress-modal-bar-track">
<div
className="progress-modal-bar-fill"
style={{ width: `${progressPercent}%` }}
/>
</div>
<span className="progress-modal-bar-text">
{progress.current} of {progress.total} pages
</span>
</div>
)}
{!progress && (
<div className="progress-modal-spinner">
<Loader2 className="spin" size={24} />
</div>
)}
{taskId && (
<p className="progress-modal-task-id">
Task ID: <code>{taskId}</code>
</p>
)}
</div>
</div>
</div>
);
}