This commit is contained in:
alorig
2025-11-19 21:56:03 +05:00
parent 7321803006
commit 38f6026e73
13 changed files with 2370 additions and 142 deletions

View File

@@ -26,10 +26,14 @@ import {
fetchKeywords,
fetchClusters,
fetchContentIdeas,
fetchTasks
fetchTasks,
fetchSiteBlueprints,
SiteBlueprint,
} from "../../services/api";
import { useSiteStore } from "../../store/siteStore";
import { useSectorStore } from "../../store/sectorStore";
import { Link } from "react-router";
import Alert from "../../components/ui/alert/Alert";
interface DashboardStats {
keywords: {
@@ -70,18 +74,29 @@ export default function PlannerDashboard() {
const [stats, setStats] = useState<DashboardStats | null>(null);
const [loading, setLoading] = useState(true);
const [lastUpdated, setLastUpdated] = useState<Date>(new Date());
const [incompleteBlueprints, setIncompleteBlueprints] = useState<SiteBlueprint[]>([]);
// Fetch real data
const fetchDashboardData = async () => {
try {
setLoading(true);
const [keywordsRes, clustersRes, ideasRes, tasksRes] = await Promise.all([
const [keywordsRes, clustersRes, ideasRes, tasksRes, blueprintsRes] = await Promise.all([
fetchKeywords({ page_size: 1000, sector_id: activeSector?.id }),
fetchClusters({ page_size: 1000, sector_id: activeSector?.id }),
fetchContentIdeas({ page_size: 1000, sector_id: activeSector?.id }),
fetchTasks({ page_size: 1000, sector_id: activeSector?.id })
fetchTasks({ page_size: 1000, sector_id: activeSector?.id }),
activeSite?.id ? fetchSiteBlueprints({ site_id: activeSite.id, page_size: 100 }) : Promise.resolve({ results: [] })
]);
// Check for incomplete blueprints
if (blueprintsRes.results) {
const incomplete = blueprintsRes.results.filter((bp: SiteBlueprint) => {
const workflow = bp.workflow_state;
return workflow && !workflow.completed && workflow.blocking_reason;
});
setIncompleteBlueprints(incomplete);
}
const keywords = keywordsRes.results || [];
const mappedKeywords = keywords.filter(k => k.cluster && k.cluster.length > 0);
@@ -458,6 +473,37 @@ export default function PlannerDashboard() {
onRefresh={fetchDashboardData}
/>
{/* Incomplete Blueprints Banner */}
{incompleteBlueprints.length > 0 && (
<Alert variant="warning" className="mb-6">
<div className="flex items-start justify-between">
<div className="flex-1">
<strong className="block mb-2">Incomplete Site Builder Workflows</strong>
<p className="text-sm mb-3">
{incompleteBlueprints.length} blueprint{incompleteBlueprints.length > 1 ? 's' : ''} {incompleteBlueprints.length > 1 ? 'have' : 'has'} incomplete workflows that need attention:
</p>
<ul className="list-disc list-inside space-y-1 text-sm mb-3">
{incompleteBlueprints.map((bp) => (
<li key={bp.id}>
<Link
to={`/sites/builder/workflow/${bp.id}`}
className="text-blue-600 dark:text-blue-400 hover:underline"
>
{bp.name}
</Link>
{bp.workflow_state?.blocking_reason && (
<span className="text-gray-600 dark:text-gray-400 ml-2">
- {bp.workflow_state.blocking_reason}
</span>
)}
</li>
))}
</ul>
</div>
</div>
</Alert>
)}
<div className="space-y-6">
{/* Key Metrics */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">