Update ProgressModal.tsx

This commit is contained in:
Desktop
2025-11-11 00:17:34 +05:00
parent 51f8e07634
commit 052332ef01

View File

@@ -28,20 +28,63 @@ export interface ProgressModalProps {
}>; // Step logs for debugging
}
// Success messages per function
const getSuccessMessage = (functionId?: string, title?: string): string => {
// Success messages per function with counts
const getSuccessMessage = (functionId?: string, title?: string, stepLogs?: any[]): string => {
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')) {
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.';
}
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.';
}
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.';
}
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 'Task completed successfully.';
@@ -158,6 +201,28 @@ export default function ProgressModal({
const steps = getStepsForFunction(functionId, title);
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
useEffect(() => {
if (!isOpen) {
@@ -215,41 +280,24 @@ export default function ProgressModal({
};
}, [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(() => {
if (status === 'completed' && onClose && !hasAutoClosedRef.current) {
if (status === 'completed' && allStepsVisuallyCompleted && onClose && !hasAutoClosedRef.current) {
hasAutoClosedRef.current = true;
// Wait 3 seconds after success alert appears
const timer = setTimeout(() => {
onClose();
}, 5000);
}, 3000);
return () => clearTimeout(timer);
}
if (status !== 'completed') {
if (status !== 'completed' || !allStepsVisuallyCompleted) {
hasAutoClosedRef.current = false;
}
}, [status, onClose]);
}, [status, allStepsVisuallyCompleted, onClose]);
// Build checklist items with visual completion state
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
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);
// Show success alert only when all steps are visually completed AND status is completed
const showSuccess = status === 'completed' && allStepsVisuallyCompleted;
const successMessage = getSuccessMessage(functionId, title, stepLogs);
return (
<Modal
@@ -287,14 +335,21 @@ export default function ProgressModal({
</div>
</div>
{/* Success Alert (shown when completed) */}
{/* Success Alert (shown when all steps are visually completed) */}
{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="flex items-start gap-3">
<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">
<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>
<p className="text-sm font-medium text-green-800 dark:text-green-300">
<div className="mb-6">
{/* Big centered check icon */}
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-full bg-green-600 dark:bg-green-700 flex items-center justify-center">
<svg className="w-10 h-10 text-white" fill="currentColor" viewBox="0 0 20 20">
<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}
</p>
</div>