Files
igny8/frontend/src/components/dashboard/QuickActionsWidget.tsx
IGNY8 VPS (Salman) 75deda304e reanme purple to info
2026-01-24 15:27:51 +00:00

244 lines
8.1 KiB
TypeScript

/**
* QuickActionsWidget - Workflow guide with explainer text
* Full-width layout with steps in 3 columns (1-3, 4-6, 7-8)
*/
import { useNavigate } from 'react-router-dom';
import Button from '../ui/button/Button';
import {
HelpCircleIcon,
} from '../../icons';
interface QuickActionsWidgetProps {
onAddKeywords?: () => void;
}
/**
* Workflow steps with solid colored backgrounds for visual distinction:
* PLANNER PIPELINE (Blue → Pink → Amber):
* - Keywords: brand/primary (blue)
* - Clusters: purple/pink
* - Ideas: warning/amber
* WRITER PIPELINE (Navy → Blue → Pink → Amber → Green):
* - Tasks: gray-dark (navy) - entry point to Writer
* - Content: brand/primary (blue)
* - Images: purple/pink
* - Review: warning/amber
* - Publish: success/green
*/
const workflowSteps = [
{
num: 1,
title: 'Keyword Library',
description: 'Import your target keywords manually or from CSV',
href: '/planner/keyword-opportunities',
actionLabel: 'Add',
gradient: 'from-brand-500 to-brand-600',
buttonTone: 'brand' as const,
},
{
num: 2,
title: 'Auto Cluster',
description: 'AI groups related keywords into content clusters',
href: '/planner/keyword-opportunities', // Clustering runs from keywords page
actionLabel: 'Cluster',
gradient: 'from-info-500 to-info-600',
buttonTone: 'brand' as const,
},
{
num: 3,
title: 'Generate Ideas',
description: 'Create content ideas from your keyword clusters',
href: '/planner/ideas',
actionLabel: 'Ideas',
gradient: 'from-warning-500 to-warning-600',
buttonTone: 'warning' as const,
},
{
num: 4,
title: 'Create Tasks',
description: 'Convert approved ideas into content tasks',
href: '/writer/tasks',
actionLabel: 'Tasks',
gradient: 'from-gray-700 to-gray-800',
buttonTone: 'neutral' as const,
},
{
num: 5,
title: 'Generate Content',
description: 'AI writes SEO-optimized articles from tasks',
href: '/writer/content',
actionLabel: 'Write',
gradient: 'from-brand-500 to-brand-600',
buttonTone: 'brand' as const,
},
{
num: 6,
title: 'Generate Images',
description: 'Create featured images and media for articles',
href: '/writer/images',
actionLabel: 'Images',
gradient: 'from-info-500 to-info-600',
buttonTone: 'brand' as const,
},
{
num: 7,
title: 'Review & Approve',
description: 'Quality check and approve generated content',
href: '/writer/review',
actionLabel: 'Review',
gradient: 'from-warning-500 to-warning-600',
buttonTone: 'warning' as const,
},
{
num: 8,
title: 'Publish to WP',
description: 'Push approved content to your WordPress site',
href: '/writer/published',
actionLabel: 'Publish',
gradient: 'from-success-500 to-success-600',
buttonTone: 'success' as const,
},
];
export default function QuickActionsWidget({ onAddKeywords }: QuickActionsWidgetProps) {
const navigate = useNavigate();
return (
<div className="bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 p-5">
{/* Header */}
<div className="flex items-center justify-between mb-4">
<h3 className="text-base font-semibold text-gray-800 dark:text-gray-200 uppercase tracking-wide">
Workflow Guide
</h3>
<Button
variant="outline"
tone="neutral"
size="sm"
startIcon={<HelpCircleIcon className="w-4 h-4" />}
onClick={() => navigate('/help')}
>
Full Help Guide
</Button>
</div>
{/* 3-Column Grid: Steps 1-3, 4-6, 7-8 */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{/* Column 1: Steps 1-3 */}
<div className="space-y-2.5">
{workflowSteps.slice(0, 3).map((step) => {
return (
<div
key={step.num}
className="flex items-center gap-3 p-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors group"
>
{/* Step Number */}
<span className={`w-6 h-6 flex items-center justify-center rounded-full bg-gradient-to-br ${step.gradient} text-sm font-semibold text-white flex-shrink-0 shadow-sm`}>
{step.num}
</span>
{/* Text Content */}
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-gray-800 dark:text-gray-200">
{step.title}
</p>
<p className="text-xs text-gray-600 dark:text-gray-400 line-clamp-1">
{step.description}
</p>
</div>
{/* Action Button - matches step number color */}
<Button
size="xs"
variant="primary"
tone={step.buttonTone}
onClick={() => navigate(step.href)}
className="flex-shrink-0"
>
{step.actionLabel}
</Button>
</div>
);
})}
</div>
{/* Column 2: Steps 4-6 */}
<div className="space-y-2.5">
{workflowSteps.slice(3, 6).map((step) => {
return (
<div
key={step.num}
className="flex items-center gap-3 p-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors group"
>
{/* Step Number */}
<span className={`w-6 h-6 flex items-center justify-center rounded-full bg-gradient-to-br ${step.gradient} text-sm font-semibold text-white flex-shrink-0 shadow-sm`}>
{step.num}
</span>
{/* Text Content */}
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-gray-800 dark:text-gray-200">
{step.title}
</p>
<p className="text-xs text-gray-600 dark:text-gray-400 line-clamp-1">
{step.description}
</p>
</div>
{/* Action Button - matches step number color */}
<Button
size="xs"
variant="primary"
tone={step.buttonTone}
onClick={() => navigate(step.href)}
className="flex-shrink-0"
>
{step.actionLabel}
</Button>
</div>
);
})}
</div>
{/* Column 3: Steps 7-8 */}
<div className="space-y-2.5">
{workflowSteps.slice(6, 8).map((step) => {
return (
<div
key={step.num}
className="flex items-center gap-3 p-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors group"
>
{/* Step Number */}
<span className={`w-6 h-6 flex items-center justify-center rounded-full bg-gradient-to-br ${step.gradient} text-sm font-semibold text-white flex-shrink-0 shadow-sm`}>
{step.num}
</span>
{/* Text Content */}
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-gray-800 dark:text-gray-200">
{step.title}
</p>
<p className="text-xs text-gray-600 dark:text-gray-400 line-clamp-1">
{step.description}
</p>
</div>
{/* Action Button - matches step number color */}
<Button
size="xs"
variant="primary"
tone={step.buttonTone}
onClick={() => navigate(step.href)}
className="flex-shrink-0"
>
{step.actionLabel}
</Button>
</div>
);
})}
</div>
</div>
</div>
);
}