refactor phase 7-8
This commit is contained in:
@@ -2,6 +2,8 @@ import { useState, useEffect, useCallback } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
import PageMeta from '../../components/common/PageMeta';
|
||||
import PageHeader from '../../components/common/PageHeader';
|
||||
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
|
||||
import ModuleMetricsFooter, { MetricItem, ProgressMetric } from '../../components/dashboard/ModuleMetricsFooter';
|
||||
import { optimizerApi, EntryPoint } from '../../api/optimizer.api';
|
||||
import { fetchContent, Content as ContentType } from '../../services/api';
|
||||
import { useToast } from '../../components/ui/toast/ToastContainer';
|
||||
@@ -9,7 +11,7 @@ import { SourceBadge, ContentSource } from '../../components/content/SourceBadge
|
||||
import { SyncStatusBadge, SyncStatus } from '../../components/content/SyncStatusBadge';
|
||||
import { ContentFilter, FilterState } from '../../components/content/ContentFilter';
|
||||
import { OptimizationScores } from '../../components/optimizer/OptimizationScores';
|
||||
import { BoltIcon, CheckCircleIcon } from '../../icons';
|
||||
import { BoltIcon, CheckCircleIcon, FileIcon } from '../../icons';
|
||||
import { useSectorStore } from '../../store/sectorStore';
|
||||
import { usePageSizeStore } from '../../store/pageSizeStore';
|
||||
|
||||
@@ -146,15 +148,18 @@ export default function OptimizerContentSelector() {
|
||||
<PageMeta title="Optimize Content" description="Select and optimize content for SEO and engagement" />
|
||||
|
||||
<div className="space-y-6">
|
||||
<PageHeader
|
||||
title="Optimize Content"
|
||||
lastUpdated={new Date()}
|
||||
badge={{
|
||||
icon: <BoltIcon />,
|
||||
color: 'orange',
|
||||
}}
|
||||
/>
|
||||
<ModuleNavigationTabs tabs={[
|
||||
{ label: 'Content', path: '/optimizer/content', icon: <FileIcon /> },
|
||||
]} />
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<PageHeader
|
||||
title="Optimize Content"
|
||||
lastUpdated={new Date()}
|
||||
badge={{
|
||||
icon: <BoltIcon />,
|
||||
color: 'orange',
|
||||
}}
|
||||
/>
|
||||
<div className="flex items-center gap-4">
|
||||
<select
|
||||
value={entryPoint}
|
||||
@@ -326,6 +331,47 @@ export default function OptimizerContentSelector() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Module Metrics Footer */}
|
||||
<ModuleMetricsFooter
|
||||
metrics={[
|
||||
{
|
||||
title: 'Total Content',
|
||||
value: totalCount.toLocaleString(),
|
||||
subtitle: `${filteredContent.length} filtered`,
|
||||
icon: <FileIcon className="w-5 h-5" />,
|
||||
accentColor: 'blue',
|
||||
href: '/optimizer/content',
|
||||
},
|
||||
{
|
||||
title: 'Optimized',
|
||||
value: content.filter(c => c.optimizer_version && c.optimizer_version > 0).length.toLocaleString(),
|
||||
subtitle: `${processing.length} processing`,
|
||||
icon: <BoltIcon className="w-5 h-5" />,
|
||||
accentColor: 'orange',
|
||||
},
|
||||
{
|
||||
title: 'Avg Score',
|
||||
value: content.length > 0 && content.some(c => c.optimization_scores?.overall_score)
|
||||
? (content
|
||||
.filter(c => c.optimization_scores?.overall_score)
|
||||
.reduce((sum, c) => sum + (c.optimization_scores?.overall_score || 0), 0) /
|
||||
content.filter(c => c.optimization_scores?.overall_score).length
|
||||
).toFixed(1)
|
||||
: '-',
|
||||
subtitle: `${content.filter(c => c.optimization_scores?.overall_score && c.optimization_scores.overall_score >= 80).length} high score`,
|
||||
icon: <CheckCircleIcon className="w-5 h-5" />,
|
||||
accentColor: 'green',
|
||||
},
|
||||
]}
|
||||
progress={{
|
||||
label: 'Content Optimization Progress',
|
||||
value: totalCount > 0
|
||||
? Math.round((content.filter(c => c.optimizer_version && c.optimizer_version > 0).length / totalCount) * 100)
|
||||
: 0,
|
||||
color: 'warning',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user