metrics adn insihigts
This commit is contained in:
@@ -29,6 +29,8 @@ import { useSectorStore } from '../../store/sectorStore';
|
||||
import { usePageSizeStore } from '../../store/pageSizeStore';
|
||||
import PageHeader from '../../components/common/PageHeader';
|
||||
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
|
||||
import ModuleMetricsFooter, { MetricItem, ProgressMetric } from '../../components/dashboard/ModuleMetricsFooter';
|
||||
import { WorkflowInsight } from '../../components/common/WorkflowInsights';
|
||||
|
||||
export default function Ideas() {
|
||||
const toast = useToast();
|
||||
@@ -76,6 +78,57 @@ export default function Ideas() {
|
||||
// Progress modal for AI functions
|
||||
const progressModal = useProgressModal();
|
||||
|
||||
// Calculate workflow insights
|
||||
const workflowInsights: WorkflowInsight[] = useMemo(() => {
|
||||
const insights: WorkflowInsight[] = [];
|
||||
const newCount = ideas.filter(i => i.status === 'new').length;
|
||||
const queuedCount = ideas.filter(i => i.status === 'queued').length;
|
||||
const completedCount = ideas.filter(i => i.status === 'completed').length;
|
||||
const queueActivationRate = totalCount > 0 ? Math.round((queuedCount / totalCount) * 100) : 0;
|
||||
const completionRate = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0;
|
||||
|
||||
if (totalCount === 0) {
|
||||
insights.push({
|
||||
type: 'info',
|
||||
message: 'Generate ideas from your keyword clusters to build your content pipeline',
|
||||
});
|
||||
return insights;
|
||||
}
|
||||
|
||||
// Queue activation insights
|
||||
if (newCount > 0 && queuedCount === 0) {
|
||||
insights.push({
|
||||
type: 'warning',
|
||||
message: `${newCount} new ideas waiting - Queue them to activate the content pipeline`,
|
||||
});
|
||||
} else if (queueActivationRate > 0 && queueActivationRate < 40) {
|
||||
insights.push({
|
||||
type: 'info',
|
||||
message: `${queueActivationRate}% of ideas queued (${queuedCount} ideas) - Queue more ideas to maintain steady content flow`,
|
||||
});
|
||||
} else if (queuedCount > 0) {
|
||||
insights.push({
|
||||
type: 'success',
|
||||
message: `${queuedCount} ideas in queue - Content pipeline is active and ready for task generation`,
|
||||
});
|
||||
}
|
||||
|
||||
// Completion velocity
|
||||
if (completionRate >= 50) {
|
||||
insights.push({
|
||||
type: 'success',
|
||||
message: `Strong completion rate (${completionRate}%) - ${completedCount} ideas converted to content`,
|
||||
});
|
||||
} else if (completionRate > 0) {
|
||||
insights.push({
|
||||
type: 'info',
|
||||
message: `${completedCount} ideas completed (${completionRate}%) - Continue queuing ideas to grow content library`,
|
||||
});
|
||||
}
|
||||
|
||||
return insights;
|
||||
}, [ideas, totalCount]);
|
||||
|
||||
// Load clusters for filter dropdown
|
||||
useEffect(() => {
|
||||
const loadClusters = async () => {
|
||||
@@ -258,6 +311,7 @@ export default function Ideas() {
|
||||
label: metric.label,
|
||||
value: metric.calculate({ ideas, totalCount }),
|
||||
accentColor: metric.accentColor,
|
||||
tooltip: (metric as any).tooltip,
|
||||
}));
|
||||
}, [pageConfig?.headerMetrics, ideas, totalCount]);
|
||||
|
||||
@@ -307,6 +361,7 @@ export default function Ideas() {
|
||||
title="Content Ideas"
|
||||
badge={{ icon: <BoltIcon />, color: 'orange' }}
|
||||
navigation={<ModuleNavigationTabs tabs={plannerTabs} />}
|
||||
workflowInsights={workflowInsights}
|
||||
/>
|
||||
<TablePageTemplate
|
||||
columns={pageConfig.columns}
|
||||
@@ -413,6 +468,48 @@ export default function Ideas() {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Module Metrics Footer - Pipeline Style with Cross-Module Links */}
|
||||
<ModuleMetricsFooter
|
||||
metrics={[
|
||||
{
|
||||
title: 'Clusters',
|
||||
value: clusters.length.toLocaleString(),
|
||||
subtitle: 'topic groups',
|
||||
icon: <GroupIcon className="w-5 h-5" />,
|
||||
accentColor: 'purple',
|
||||
href: '/planner/clusters',
|
||||
},
|
||||
{
|
||||
title: 'Ready to Queue',
|
||||
value: ideas.filter(i => i.status === 'new').length.toLocaleString(),
|
||||
subtitle: 'awaiting approval',
|
||||
icon: <BoltIcon className="w-5 h-5" />,
|
||||
accentColor: 'orange',
|
||||
},
|
||||
{
|
||||
title: 'In Queue',
|
||||
value: ideas.filter(i => i.status === 'queued').length.toLocaleString(),
|
||||
subtitle: 'ready for tasks',
|
||||
icon: <ListIcon className="w-5 h-5" />,
|
||||
accentColor: 'blue',
|
||||
href: '/writer/tasks',
|
||||
},
|
||||
{
|
||||
title: 'Content Created',
|
||||
value: ideas.filter(i => i.status === 'completed').length.toLocaleString(),
|
||||
subtitle: `${totalCount > 0 ? Math.round((ideas.filter(i => i.status === 'completed').length / totalCount) * 100) : 0}% completion`,
|
||||
icon: <BoltIcon className="w-5 h-5" />,
|
||||
accentColor: 'green',
|
||||
href: '/writer/content',
|
||||
},
|
||||
]}
|
||||
progress={{
|
||||
label: 'Idea-to-Content Pipeline: Ideas successfully converted into written content',
|
||||
value: totalCount > 0 ? Math.round((ideas.filter(i => i.status === 'completed').length / totalCount) * 100) : 0,
|
||||
color: 'success',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Progress Modal for AI Functions */}
|
||||
<ProgressModal
|
||||
isOpen={progressModal.isOpen}
|
||||
|
||||
Reference in New Issue
Block a user