import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { PageHeader } from '../../components/layout'; import StatsGrid from '../../components/ui/Stats/StatsGrid'; import RealTimeAlerts from '../../components/domain/dashboard/RealTimeAlerts'; import PendingPOApprovals from '../../components/domain/dashboard/PendingPOApprovals'; import TodayProduction from '../../components/domain/dashboard/TodayProduction'; import { useTenant } from '../../stores/tenant.store'; import { useDemoTour, shouldStartTour, clearTourStartPending } from '../../features/demo-onboarding'; import { useDashboardStats } from '../../api/hooks/dashboard'; import { AlertTriangle, Clock, Euro, Package } from 'lucide-react'; const DashboardPage: React.FC = () => { const { t } = useTranslation(); const navigate = useNavigate(); const { availableTenants, currentTenant } = useTenant(); const { startTour } = useDemoTour(); const isDemoMode = localStorage.getItem('demo_mode') === 'true'; // Fetch real dashboard statistics const { data: dashboardStats, isLoading: isLoadingStats, error: statsError } = useDashboardStats( currentTenant?.id || '', { enabled: !!currentTenant?.id, } ); useEffect(() => { console.log('[Dashboard] Demo mode:', isDemoMode); console.log('[Dashboard] Should start tour:', shouldStartTour()); console.log('[Dashboard] SessionStorage demo_tour_should_start:', sessionStorage.getItem('demo_tour_should_start')); if (isDemoMode && shouldStartTour()) { console.log('[Dashboard] Starting tour in 1.5s...'); const timer = setTimeout(() => { console.log('[Dashboard] Executing startTour()'); startTour(); clearTourStartPending(); }, 1500); return () => clearTimeout(timer); } }, [isDemoMode, startTour]); const handleViewAllProcurement = () => { navigate('/app/operations/procurement'); }; const handleViewAllProduction = () => { navigate('/app/operations/production'); }; const handleOrderItem = (itemId: string) => { console.log('Ordering item:', itemId); navigate('/app/operations/procurement'); }; const handleStartBatch = (batchId: string) => { console.log('Starting production batch:', batchId); }; const handlePauseBatch = (batchId: string) => { console.log('Pausing production batch:', batchId); }; const handleViewDetails = (id: string) => { console.log('Viewing details for:', id); }; const handleApprovePO = (poId: string) => { console.log('Approved PO:', poId); }; const handleRejectPO = (poId: string) => { console.log('Rejected PO:', poId); }; const handleViewPODetails = (poId: string) => { console.log('Viewing PO details:', poId); navigate(`/app/suppliers/purchase-orders/${poId}`); }; const handleViewAllPOs = () => { navigate('/app/operations/procurement'); }; // Build stats from real API data const criticalStats = React.useMemo(() => { if (!dashboardStats) { // Return loading/empty state return []; } // Format currency values const formatCurrency = (value: number): string => { return `${dashboardStats.salesCurrency}${value.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0, })}`; }; // Determine trend direction const getTrendDirection = (value: number): 'up' | 'down' | 'neutral' => { if (value > 0) return 'up'; if (value < 0) return 'down'; return 'neutral'; }; // Build subtitle for sales const salesChange = dashboardStats.salesToday * (dashboardStats.salesTrend / 100); const salesSubtitle = salesChange > 0 ? `+${formatCurrency(salesChange)} ${t('dashboard:messages.more_than_yesterday', 'more than yesterday')}` : salesChange < 0 ? `${formatCurrency(Math.abs(salesChange))} ${t('dashboard:messages.less_than_yesterday', 'less than yesterday')}` : t('dashboard:messages.same_as_yesterday', 'Same as yesterday'); // Build subtitle for products const productsChange = Math.round(dashboardStats.productsSoldToday * (dashboardStats.productsSoldTrend / 100)); const productsSubtitle = productsChange !== 0 ? `${productsChange > 0 ? '+' : ''}${productsChange} ${t('dashboard:messages.more_units', 'units')}` : t('dashboard:messages.same_as_yesterday', 'Same as yesterday'); return [ { title: t('dashboard:stats.sales_today', 'Sales Today'), value: formatCurrency(dashboardStats.salesToday), icon: Euro, variant: 'success' as const, trend: { value: Math.abs(dashboardStats.salesTrend), direction: getTrendDirection(dashboardStats.salesTrend), label: t('dashboard:trends.vs_yesterday', '% vs yesterday') }, subtitle: salesSubtitle }, { title: t('dashboard:stats.pending_orders', 'Pending Orders'), value: dashboardStats.pendingOrders.toString(), icon: Clock, variant: dashboardStats.pendingOrders > 10 ? ('warning' as const) : ('info' as const), trend: dashboardStats.ordersTrend !== 0 ? { value: Math.abs(dashboardStats.ordersTrend), direction: getTrendDirection(dashboardStats.ordersTrend), label: t('dashboard:trends.vs_yesterday', '% vs yesterday') } : undefined, subtitle: dashboardStats.pendingOrders > 0 ? t('dashboard:messages.require_attention', 'Require attention') : t('dashboard:messages.all_caught_up', 'All caught up!') }, { title: t('dashboard:stats.products_sold', 'Products Sold'), value: dashboardStats.productsSoldToday.toString(), icon: Package, variant: 'info' as const, trend: dashboardStats.productsSoldTrend !== 0 ? { value: Math.abs(dashboardStats.productsSoldTrend), direction: getTrendDirection(dashboardStats.productsSoldTrend), label: t('dashboard:trends.vs_yesterday', '% vs yesterday') } : undefined, subtitle: productsSubtitle }, { title: t('dashboard:stats.stock_alerts', 'Critical Stock'), value: dashboardStats.criticalStock.toString(), icon: AlertTriangle, variant: dashboardStats.criticalStock > 0 ? ('error' as const) : ('success' as const), trend: undefined, // Stock alerts don't have historical trends subtitle: dashboardStats.criticalStock > 0 ? t('dashboard:messages.action_required', 'Action required') : t('dashboard:messages.stock_healthy', 'Stock levels healthy') } ]; }, [dashboardStats, t]); return (
{/* Critical Metrics using StatsGrid */}
{isLoadingStats ? (
{[1, 2, 3, 4].map((i) => (
))}
) : statsError ? (

{t('dashboard:errors.failed_to_load_stats', 'Failed to load dashboard statistics. Please try again.')}

) : ( )}
{/* Dashboard Content - Four Main Sections */}
{/* 1. Real-time Alerts */}
{/* 2. Pending PO Approvals - What purchase orders need approval? */}
{/* 3. Today's Production - What needs to be produced today? */}
); }; export default DashboardPage;