Update ProgressModal.tsx
This commit is contained in:
@@ -28,20 +28,63 @@ export interface ProgressModalProps {
|
|||||||
}>; // Step logs for debugging
|
}>; // Step logs for debugging
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success messages per function
|
// Success messages per function with counts
|
||||||
const getSuccessMessage = (functionId?: string, title?: string): string => {
|
const getSuccessMessage = (functionId?: string, title?: string, stepLogs?: any[]): string => {
|
||||||
const funcName = functionId?.toLowerCase() || title?.toLowerCase() || '';
|
const funcName = functionId?.toLowerCase() || title?.toLowerCase() || '';
|
||||||
|
|
||||||
|
// Extract counts from step logs
|
||||||
|
const extractCount = (pattern: RegExp, logs: any[]): string => {
|
||||||
|
for (const log of logs) {
|
||||||
|
const match = log.message?.match(pattern);
|
||||||
|
if (match && match[1]) return match[1];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
if (funcName.includes('cluster')) {
|
if (funcName.includes('cluster')) {
|
||||||
|
const keywordCount = extractCount(/(\d+)\s+keyword/i, stepLogs || []);
|
||||||
|
const clusterCount = extractCount(/(\d+)\s+cluster/i, stepLogs || []);
|
||||||
|
|
||||||
|
if (keywordCount && clusterCount) {
|
||||||
|
return `Clustering complete — ${clusterCount} cluster${clusterCount !== '1' ? 's' : ''} created from ${keywordCount} keyword${keywordCount !== '1' ? 's' : ''}.`;
|
||||||
|
} else if (clusterCount) {
|
||||||
|
return `Clustering complete — ${clusterCount} cluster${clusterCount !== '1' ? 's' : ''} created.`;
|
||||||
|
} else if (keywordCount) {
|
||||||
|
return `Clustering complete — processed ${keywordCount} keyword${keywordCount !== '1' ? 's' : ''}.`;
|
||||||
|
}
|
||||||
return 'Clustering complete — keywords grouped into meaningful clusters.';
|
return 'Clustering complete — keywords grouped into meaningful clusters.';
|
||||||
}
|
}
|
||||||
if (funcName.includes('idea')) {
|
if (funcName.includes('idea')) {
|
||||||
|
const clusterCount = extractCount(/(\d+)\s+cluster/i, stepLogs || []);
|
||||||
|
const ideaCount = extractCount(/(\d+)\s+idea/i, stepLogs || []);
|
||||||
|
|
||||||
|
if (ideaCount) {
|
||||||
|
return `Content ideas created successfully — ${ideaCount} idea${ideaCount !== '1' ? 's' : ''} generated.`;
|
||||||
|
} else if (clusterCount) {
|
||||||
|
return `Content ideas created successfully — generated for ${clusterCount} cluster${clusterCount !== '1' ? 's' : ''}.`;
|
||||||
|
}
|
||||||
return 'Content ideas and outlines created successfully.';
|
return 'Content ideas and outlines created successfully.';
|
||||||
}
|
}
|
||||||
if (funcName.includes('content')) {
|
if (funcName.includes('content')) {
|
||||||
|
const taskCount = extractCount(/(\d+)\s+task/i, stepLogs || []);
|
||||||
|
const articleCount = extractCount(/(\d+)\s+article/i, stepLogs || []);
|
||||||
|
|
||||||
|
if (articleCount) {
|
||||||
|
return `Article${articleCount !== '1' ? 's' : ''} drafted successfully — ${articleCount} article${articleCount !== '1' ? 's' : ''} generated.`;
|
||||||
|
} else if (taskCount) {
|
||||||
|
return `Article${taskCount !== '1' ? 's' : ''} drafted successfully — ${taskCount} task${taskCount !== '1' ? 's' : ''} completed.`;
|
||||||
|
}
|
||||||
return 'Article drafted successfully.';
|
return 'Article drafted successfully.';
|
||||||
}
|
}
|
||||||
if (funcName.includes('image')) {
|
if (funcName.includes('image')) {
|
||||||
|
const imageCount = extractCount(/(\d+)\s+image/i, stepLogs || []);
|
||||||
|
const taskCount = extractCount(/(\d+)\s+task/i, stepLogs || []);
|
||||||
|
|
||||||
|
if (imageCount) {
|
||||||
|
return `Images created successfully — ${imageCount} image${imageCount !== '1' ? 's' : ''} generated.`;
|
||||||
|
} else if (taskCount) {
|
||||||
|
return `Images created successfully — ${taskCount} task${taskCount !== '1' ? 's' : ''} completed.`;
|
||||||
|
}
|
||||||
return 'Images created and saved successfully.';
|
return 'Images created and saved successfully.';
|
||||||
}
|
}
|
||||||
return 'Task completed successfully.';
|
return 'Task completed successfully.';
|
||||||
@@ -158,6 +201,28 @@ export default function ProgressModal({
|
|||||||
const steps = getStepsForFunction(functionId, title);
|
const steps = getStepsForFunction(functionId, title);
|
||||||
const currentPhase = getCurrentPhase(stepLogs, percentage);
|
const currentPhase = getCurrentPhase(stepLogs, percentage);
|
||||||
|
|
||||||
|
// Build checklist items with visual completion state (needed for allStepsVisuallyCompleted)
|
||||||
|
const checklistItems = steps.map((step) => {
|
||||||
|
const actuallyCompleted = isStepCompleted(step.phase, currentPhase, stepLogs);
|
||||||
|
const visuallyCompleted = visuallyCompletedSteps.has(step.phase);
|
||||||
|
const inProgress = isStepInProgress(step.phase, currentPhase) && !visuallyCompleted;
|
||||||
|
|
||||||
|
// Get user-friendly message from step logs if available (includes counts from backend)
|
||||||
|
const stepLog = stepLogs.find(log => log.stepName === step.phase);
|
||||||
|
const stepMessage = stepLog?.message || step.label;
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: stepMessage,
|
||||||
|
phase: step.phase,
|
||||||
|
completed: visuallyCompleted,
|
||||||
|
inProgress,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if all steps are visually completed
|
||||||
|
const allStepsVisuallyCompleted = steps.length > 0 &&
|
||||||
|
steps.every(step => visuallyCompletedSteps.has(step.phase));
|
||||||
|
|
||||||
// Track step completions with 2-second delay between each step
|
// Track step completions with 2-second delay between each step
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
@@ -215,41 +280,24 @@ export default function ProgressModal({
|
|||||||
};
|
};
|
||||||
}, [isOpen, currentPhase, stepLogs, steps, visuallyCompletedSteps]);
|
}, [isOpen, currentPhase, stepLogs, steps, visuallyCompletedSteps]);
|
||||||
|
|
||||||
// Auto-close on completion after 5 seconds (increased to allow all steps to show)
|
// Auto-close on completion after all steps are visually completed + 3 seconds
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (status === 'completed' && onClose && !hasAutoClosedRef.current) {
|
if (status === 'completed' && allStepsVisuallyCompleted && onClose && !hasAutoClosedRef.current) {
|
||||||
hasAutoClosedRef.current = true;
|
hasAutoClosedRef.current = true;
|
||||||
|
// Wait 3 seconds after success alert appears
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
onClose();
|
onClose();
|
||||||
}, 5000);
|
}, 3000);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}
|
}
|
||||||
if (status !== 'completed') {
|
if (status !== 'completed' || !allStepsVisuallyCompleted) {
|
||||||
hasAutoClosedRef.current = false;
|
hasAutoClosedRef.current = false;
|
||||||
}
|
}
|
||||||
}, [status, onClose]);
|
}, [status, allStepsVisuallyCompleted, onClose]);
|
||||||
|
|
||||||
// Build checklist items with visual completion state
|
// Show success alert only when all steps are visually completed AND status is completed
|
||||||
const checklistItems = steps.map((step) => {
|
const showSuccess = status === 'completed' && allStepsVisuallyCompleted;
|
||||||
const actuallyCompleted = isStepCompleted(step.phase, currentPhase, stepLogs);
|
const successMessage = getSuccessMessage(functionId, title, stepLogs);
|
||||||
const visuallyCompleted = visuallyCompletedSteps.has(step.phase);
|
|
||||||
const inProgress = isStepInProgress(step.phase, currentPhase) && !visuallyCompleted;
|
|
||||||
|
|
||||||
// Get user-friendly message from step logs if available
|
|
||||||
const stepLog = stepLogs.find(log => log.stepName === step.phase);
|
|
||||||
const stepMessage = stepLog?.message || step.label;
|
|
||||||
|
|
||||||
return {
|
|
||||||
label: stepMessage,
|
|
||||||
phase: step.phase,
|
|
||||||
completed: visuallyCompleted, // Use visual completion state
|
|
||||||
inProgress,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show success alert when completed
|
|
||||||
const showSuccess = status === 'completed';
|
|
||||||
const successMessage = getSuccessMessage(functionId, title);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@@ -287,14 +335,21 @@ export default function ProgressModal({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Success Alert (shown when completed) */}
|
{/* Success Alert (shown when all steps are visually completed) */}
|
||||||
{showSuccess && (
|
{showSuccess && (
|
||||||
<div className="mb-6 p-4 rounded-lg bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800">
|
<div className="mb-6">
|
||||||
<div className="flex items-start gap-3">
|
{/* Big centered check icon */}
|
||||||
<svg className="w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<div className="flex justify-center mb-4">
|
||||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
<div className="w-16 h-16 rounded-full bg-green-600 dark:bg-green-700 flex items-center justify-center">
|
||||||
</svg>
|
<svg className="w-10 h-10 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<p className="text-sm font-medium text-green-800 dark:text-green-300">
|
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Dark success alert box with centered text */}
|
||||||
|
<div className="p-5 rounded-lg bg-green-600 dark:bg-green-700 border border-green-700 dark:border-green-600">
|
||||||
|
<p className="text-base font-semibold text-white text-center">
|
||||||
{successMessage}
|
{successMessage}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user