/** * Dashboard Home Page * * Main dashboard with KPIs, charts, and alerts */ 'use client'; import { useQuery } from '@tanstack/react-query'; import { dashboardApi, bookingsApi } from '@/lib/api'; import Link from 'next/link'; import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts'; export default function DashboardPage() { // Fetch dashboard data const { data: kpis, isLoading: kpisLoading } = useQuery({ queryKey: ['dashboard', 'kpis'], queryFn: () => dashboardApi.getKPIs(), }); const { data: chartData, isLoading: chartLoading } = useQuery({ queryKey: ['dashboard', 'bookings-chart'], queryFn: () => dashboardApi.getBookingsChart(), }); const { data: tradeLanes, isLoading: tradeLanesLoading } = useQuery({ queryKey: ['dashboard', 'top-trade-lanes'], queryFn: () => dashboardApi.getTopTradeLanes(), }); const { data: alerts, isLoading: alertsLoading } = useQuery({ queryKey: ['dashboard', 'alerts'], queryFn: () => dashboardApi.getAlerts(), }); const { data: recentBookings, isLoading: bookingsLoading } = useQuery({ queryKey: ['bookings', 'recent'], queryFn: () => bookingsApi.list({ limit: 5 }), }); // Format chart data for Recharts const formattedChartData = chartData ? chartData.labels.map((label, index) => ({ month: label, bookings: chartData.data[index], })) : []; // Format change percentage const formatChange = (value: number) => { const sign = value >= 0 ? '+' : ''; return `${sign}${value.toFixed(1)}%`; }; // Get change color const getChangeColor = (value: number) => { if (value > 0) return 'text-green-600'; if (value < 0) return 'text-red-600'; return 'text-gray-600'; }; // Get alert color const getAlertColor = (severity: string) => { const colors = { critical: 'bg-red-100 border-red-500 text-red-800', high: 'bg-orange-100 border-orange-500 text-orange-800', medium: 'bg-yellow-100 border-yellow-500 text-yellow-800', low: 'bg-blue-100 border-blue-500 text-blue-800', }; return colors[severity as keyof typeof colors] || colors.low; }; return (
{/* Welcome Section */}

Welcome back!

Here's what's happening with your shipments today.

{/* KPI Cards */}
{kpisLoading ? ( // Loading skeletons Array.from({ length: 4 }).map((_, i) => (
)) ) : ( <>

Bookings This Month

{kpis?.bookingsThisMonth || 0}

📦
{formatChange(kpis?.bookingsThisMonthChange || 0)} vs last month

Total TEUs

{kpis?.totalTEUs || 0}

📊
{formatChange(kpis?.totalTEUsChange || 0)} vs last month

Estimated Revenue

${(kpis?.estimatedRevenue || 0).toLocaleString()}

💰
{formatChange(kpis?.estimatedRevenueChange || 0)} vs last month

Pending Confirmations

{kpis?.pendingConfirmations || 0}

{formatChange(kpis?.pendingConfirmationsChange || 0)} vs last month
)}
{/* Alerts Section */} {!alertsLoading && alerts && alerts.length > 0 && (

⚠️ Alerts & Notifications

{alerts.slice(0, 5).map(alert => (

{alert.title}

{alert.message}

{alert.bookingNumber && ( View Booking {alert.bookingNumber} )}
{alert.severity}
))}
)} {/* Charts Section */}
{/* Bookings Trend Chart */}

Bookings Trend (6 Months)

{chartLoading ? (
) : ( )}
{/* Top Trade Lanes Chart */}

Top 5 Trade Lanes

{tradeLanesLoading ? (
) : ( )}
{/* Quick Actions */}
🔍

Search Rates

Find the best shipping rates

New Booking

Create a new shipment

📋

My Bookings

View all your shipments

{/* Recent Bookings */}

Recent Bookings

View All →
{bookingsLoading ? (
{Array.from({ length: 3 }).map((_, i) => (
))}
) : recentBookings && recentBookings.bookings.length > 0 ? (
{recentBookings.bookings.map((booking: any) => (
📦
{booking.bookingNumber}
{new Date(booking.createdAt).toLocaleDateString()}
{booking.status}
))}
) : (
📦

No bookings yet

Create your first booking to get started

Create Booking
)}
); }