244 lines
8.1 KiB
TypeScript
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>
|
|
);
|
|
}
|