// ================================================================ // frontend/src/pages/app/NewDashboardPage.tsx // ================================================================ /** * JTBD-Aligned Dashboard Page * * Complete redesign based on Jobs To Be Done methodology. * Focused on answering: "What requires my attention right now?" * * Key principles: * - Automation-first (show what system did) * - Action-oriented (prioritize tasks) * - Progressive disclosure (show 20% that matters 80%) * - Mobile-first (one-handed operation) * - Trust-building (explain system reasoning) */ import React from 'react'; import { useNavigate } from 'react-router-dom'; import { RefreshCw, ExternalLink } from 'lucide-react'; import { useTenant } from '../../stores/tenant.store'; import { useBakeryHealthStatus, useOrchestrationSummary, useActionQueue, useProductionTimeline, useInsights, useApprovePurchaseOrder, useStartProductionBatch, usePauseProductionBatch, } from '../../api/hooks/newDashboard'; import { HealthStatusCard } from '../../components/dashboard/HealthStatusCard'; import { ActionQueueCard } from '../../components/dashboard/ActionQueueCard'; import { OrchestrationSummaryCard } from '../../components/dashboard/OrchestrationSummaryCard'; import { ProductionTimelineCard } from '../../components/dashboard/ProductionTimelineCard'; import { InsightsGrid } from '../../components/dashboard/InsightsGrid'; export function NewDashboardPage() { const navigate = useNavigate(); const { currentTenant } = useTenant(); const tenantId = currentTenant?.id || ''; // Data fetching const { data: healthStatus, isLoading: healthLoading, refetch: refetchHealth, } = useBakeryHealthStatus(tenantId); const { data: orchestrationSummary, isLoading: orchestrationLoading, refetch: refetchOrchestration, } = useOrchestrationSummary(tenantId); const { data: actionQueue, isLoading: actionQueueLoading, refetch: refetchActionQueue, } = useActionQueue(tenantId); const { data: productionTimeline, isLoading: timelineLoading, refetch: refetchTimeline, } = useProductionTimeline(tenantId); const { data: insights, isLoading: insightsLoading, refetch: refetchInsights, } = useInsights(tenantId); // Mutations const approvePO = useApprovePurchaseOrder(); const startBatch = useStartProductionBatch(); const pauseBatch = usePauseProductionBatch(); // Handlers const handleApprove = async (actionId: string) => { try { await approvePO.mutateAsync({ tenantId, poId: actionId }); // Refetch to update UI refetchActionQueue(); refetchHealth(); } catch (error) { console.error('Error approving PO:', error); } }; const handleViewDetails = (actionId: string) => { // Navigate to appropriate detail page based on action type navigate(`/app/operations/procurement`); }; const handleModify = (actionId: string) => { navigate(`/app/operations/procurement`); }; const handleStartBatch = async (batchId: string) => { try { await startBatch.mutateAsync({ tenantId, batchId }); refetchTimeline(); refetchHealth(); } catch (error) { console.error('Error starting batch:', error); } }; const handlePauseBatch = async (batchId: string) => { try { await pauseBatch.mutateAsync({ tenantId, batchId }); refetchTimeline(); refetchHealth(); } catch (error) { console.error('Error pausing batch:', error); } }; const handleRefreshAll = () => { refetchHealth(); refetchOrchestration(); refetchActionQueue(); refetchTimeline(); refetchInsights(); }; return (
Your bakery at a glance