reaminig 5-t-9
This commit is contained in:
118
site-builder/src/components/common/ProgressModal.css
Normal file
118
site-builder/src/components/common/ProgressModal.css
Normal file
@@ -0,0 +1,118 @@
|
||||
.progress-modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.progress-modal {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.progress-modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.progress-modal-header h3 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.progress-modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.progress-modal-close:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.progress-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.progress-modal-message {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.progress-modal-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.progress-modal-bar-track {
|
||||
height: 8px;
|
||||
background: #e5e7eb;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-modal-bar-fill {
|
||||
height: 100%;
|
||||
background: #3b82f6;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.progress-modal-bar-text {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.progress-modal-spinner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.progress-modal-spinner .spin {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.progress-modal-task-id {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.progress-modal-task-id code {
|
||||
background: #f3f4f6;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
76
site-builder/src/components/common/ProgressModal.tsx
Normal file
76
site-builder/src/components/common/ProgressModal.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user