diff --git a/frontend/src/components/dashboard/EnhancedMetricCard.tsx b/frontend/src/components/dashboard/EnhancedMetricCard.tsx index df3541b7..837bc169 100644 --- a/frontend/src/components/dashboard/EnhancedMetricCard.tsx +++ b/frontend/src/components/dashboard/EnhancedMetricCard.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useState } from "react"; +import React, { ReactNode, useState } from "react"; import { Link } from "react-router"; import { ArrowUpIcon, ArrowDownIcon } from "../../icons"; import { EnhancedTooltip } from "../ui/tooltip/EnhancedTooltip"; @@ -131,9 +131,9 @@ export default function EnhancedMetricCard({ )}
-
{icon}
+ {React.cloneElement(icon as React.ReactElement, { className: `${colors.icon} size-6` })}
diff --git a/frontend/src/components/dashboard/WorkflowPipeline.tsx b/frontend/src/components/dashboard/WorkflowPipeline.tsx index fcf71765..b325893a 100644 --- a/frontend/src/components/dashboard/WorkflowPipeline.tsx +++ b/frontend/src/components/dashboard/WorkflowPipeline.tsx @@ -60,7 +60,16 @@ export default function WorkflowPipeline({ return (
-
+
+ {steps.map((step, index) => { const isLast = index === steps.length - 1; const nextStep = !isLast ? steps[index + 1] : null; diff --git a/frontend/src/components/sample-componeents/tasks-list-sample.html b/frontend/src/components/sample-componeents/tasks-list-sample.html index e69de29b..ded288db 100644 --- a/frontend/src/components/sample-componeents/tasks-list-sample.html +++ b/frontend/src/components/sample-componeents/tasks-list-sample.html @@ -0,0 +1,788 @@ +
+ +
+
+
+ + + + + + + +
+ +
+ + + +
+
+
+ + + +
+ +
+
+

+ To Do + + 3 + +

+ +
+ + +
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Marketing + + +
+
+ + + + + Tomorrow + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+
+
+ + + + + Jan 8, 2027 + + + + + + + + 2 + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Marketing + + +
+
+ + + + + Feb 12, 2027 + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+
+ + +
+
+

+ In Progress + + 4 + +

+ +
+ + +
+
+ + +
+
+
+ + + + + + + +
+ +
+
+
+ + + + + Today + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Template + + +
+
+ + + + + Feb 12, 2027 + + + + + + + + 8 + + + + + + + + 2 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+
+
+ + + + + Feb 12, 2027 + + + + + + + + 8 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+
+
+ + + + + Mar 08, 2027 + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+
+ + +
+
+

+ Completed + + 4 + +

+ +
+ + +
+
+ + +
+
+
+ + + + + + + +
+ +
+
+
+ + + + + Tomorrow + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Development + + +
+
+ + + + + Jan 8, 2027 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Marketing + + +
+
+ + + + + Jan 8, 2027 + + + + + + + + 2 + + + + + + + + 1 + +
+ +
+ user +
+
+
+
+
+ + +
+
+
+ + + + + + + +
+ +
+ + Template + + +
+
+ + + + + Feb 12, 2027 + + + + + + + + 8 + +
+ +
+ user +
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/frontend/src/components/ui/tooltip/EnhancedTooltip.tsx b/frontend/src/components/ui/tooltip/EnhancedTooltip.tsx index 73faf165..b29b3260 100644 --- a/frontend/src/components/ui/tooltip/EnhancedTooltip.tsx +++ b/frontend/src/components/ui/tooltip/EnhancedTooltip.tsx @@ -66,7 +66,7 @@ export const EnhancedTooltip: React.FC = ({
= ({
{children} {text} diff --git a/frontend/src/pages/Planner/Dashboard.tsx b/frontend/src/pages/Planner/Dashboard.tsx index 4ff1547a..193f3f27 100644 --- a/frontend/src/pages/Planner/Dashboard.tsx +++ b/frontend/src/pages/Planner/Dashboard.tsx @@ -27,6 +27,7 @@ import { } from "../../services/api"; import { useSiteStore } from "../../store/siteStore"; import { useSectorStore } from "../../store/sectorStore"; +import SectorSelector from "../../components/common/SectorSelector"; interface DashboardStats { keywords: { @@ -184,15 +185,14 @@ export default function PlannerDashboard() { // Initial load and periodic refresh useEffect(() => { - if (!activeSector?.id) return; - + // Allow loading for all sectors (when activeSector is null) or specific sector fetchDashboardData(); // Refresh every 30 seconds const interval = setInterval(fetchDashboardData, 30000); return () => clearInterval(interval); - }, [activeSector?.id]); + }, [activeSector?.id, activeSite?.id]); // Calculate percentages const keywordMappingPct = useMemo(() => { @@ -227,13 +227,45 @@ export default function PlannerDashboard() { fontFamily: 'Outfit' }, dataLabels: { - enabled: true, - formatter: (val: number) => `${Math.round(val)}%` + enabled: false // Disable labels on pie slices }, plotOptions: { pie: { donut: { - size: '65%' + size: '70%', + labels: { + show: true, + name: { + show: true, + fontSize: '14px', + fontWeight: 600, + color: '#374151', + fontFamily: 'Outfit' + }, + value: { + show: true, + fontSize: '20px', + fontWeight: 700, + color: '#465FFF', + fontFamily: 'Outfit', + formatter: (val: string) => { + const total = Object.values(stats.keywords.byStatus).reduce((a, b) => a + b, 0); + return total > 0 ? total.toString() : '0'; + } + }, + total: { + show: true, + label: 'Total', + fontSize: '12px', + fontWeight: 500, + color: '#6B7280', + fontFamily: 'Outfit', + formatter: () => { + const total = Object.values(stats.keywords.byStatus).reduce((a, b) => a + b, 0); + return total.toString(); + } + } + } } } } @@ -365,17 +397,23 @@ export default function PlannerDashboard() { ); } - if (!stats) { + if (!stats && !loading) { return ( <>
-

No data available. Please select a sector.

+

+ {activeSector ? 'No data available for the selected sector.' : 'No data available. Select a sector or wait for data to load.'} +

); } + if (!stats) { + return null; // Still loading + } + const workflowSteps = [ { number: 1, @@ -430,20 +468,49 @@ export default function PlannerDashboard() {
- {/* Header with last updated */} -
-
+ {/* Header with site/sector info and controls */} +
+

Planner Dashboard

-

- Last updated: {lastUpdated.toLocaleTimeString()} -

+
+

+ Last updated: {lastUpdated.toLocaleTimeString()} +

+ {activeSite && ( + <> + +

+ Site: {activeSite.name} +

+ + )} + {activeSector && ( + <> + +

+ Sector: {activeSector.name} +

+ + )} + {!activeSector && ( + <> + +

+ Sector: All Sectors +

+ + )} +
+
+
+ +
-
{/* Hero Section - Key Metric */} diff --git a/frontend/src/pages/Writer/Dashboard.tsx b/frontend/src/pages/Writer/Dashboard.tsx index 553c8c60..2ee04531 100644 --- a/frontend/src/pages/Writer/Dashboard.tsx +++ b/frontend/src/pages/Writer/Dashboard.tsx @@ -26,6 +26,7 @@ import { } from "../../services/api"; import { useSiteStore } from "../../store/siteStore"; import { useSectorStore } from "../../store/sectorStore"; +import SectorSelector from "../../components/common/SectorSelector"; interface WriterStats { tasks: { @@ -226,15 +227,14 @@ export default function WriterDashboard() { // Initial load and periodic refresh useEffect(() => { - if (!activeSector?.id) return; - + // Allow loading for all sectors (when activeSector is null) or specific sector fetchDashboardData(); // Refresh every 30 seconds const interval = setInterval(fetchDashboardData, 30000); return () => clearInterval(interval); - }, [activeSector?.id]); + }, [activeSector?.id, activeSite?.id]); // Chart data for tasks by status const tasksStatusChart = useMemo(() => { @@ -253,13 +253,45 @@ export default function WriterDashboard() { fontFamily: 'Outfit' }, dataLabels: { - enabled: true, - formatter: (val: number) => `${Math.round(val)}%` + enabled: false // Disable labels on pie slices }, plotOptions: { pie: { donut: { - size: '65%' + size: '70%', + labels: { + show: true, + name: { + show: true, + fontSize: '14px', + fontWeight: 600, + color: '#374151', + fontFamily: 'Outfit' + }, + value: { + show: true, + fontSize: '20px', + fontWeight: 700, + color: '#465FFF', + fontFamily: 'Outfit', + formatter: (val: string) => { + const total = Object.values(stats.tasks.byStatus).reduce((a, b) => a + b, 0); + return total > 0 ? total.toString() : '0'; + } + }, + total: { + show: true, + label: 'Total', + fontSize: '12px', + fontWeight: 500, + color: '#6B7280', + fontFamily: 'Outfit', + formatter: () => { + const total = Object.values(stats.tasks.byStatus).reduce((a, b) => a + b, 0); + return total.toString(); + } + } + } } } } @@ -435,17 +467,23 @@ export default function WriterDashboard() { ); } - if (!stats) { + if (!stats && !loading) { return ( <>
-

No data available. Please select a sector.

+

+ {activeSector ? 'No data available for the selected sector.' : 'No data available. Select a sector or wait for data to load.'} +

); } + if (!stats) { + return null; // Still loading + } + const workflowSteps = [ { number: 1, @@ -509,20 +547,49 @@ export default function WriterDashboard() {
- {/* Header with last updated */} -
-
+ {/* Header with site/sector info and controls */} +
+

Writer Dashboard

-

- Last updated: {lastUpdated.toLocaleTimeString()} -

+
+

+ Last updated: {lastUpdated.toLocaleTimeString()} +

+ {activeSite && ( + <> + +

+ Site: {activeSite.name} +

+ + )} + {activeSector && ( + <> + +

+ Sector: {activeSector.name} +

+ + )} + {!activeSector && ( + <> + +

+ Sector: All Sectors +

+ + )} +
+
+
+ +
-
{/* Hero Section - Key Metric */}