import { auth } from "@/auth";
import { db } from "@/lib/db";
import { StatCard } from "@/components/dashboard/stat-card";
import { SpendCharts } from "@/components/dashboard/spend-charts";
import { PoStatusBadge } from "@/components/po/po-status-badge";
import { formatCurrency, formatDate } from "@/lib/utils";
import { FileText, Clock, CheckCircle, DollarSign } from "lucide-react";
import Link from "next/link";
import type { Metadata } from "next";
export const metadata: Metadata = { title: "Dashboard" };
export default async function DashboardPage() {
const session = await auth();
if (!session?.user) return null;
const { role, id: userId } = session.user;
if (role === "TECHNICAL" || role === "MANNING" || role === "SUPERUSER") {
return ;
}
if (role === "MANAGER") {
return ;
}
if (role === "ACCOUNTS") {
return ;
}
return ;
}
async function SubmitterDashboard({ userId }: { userId: string }) {
const [openCount, pendingCount, closedCount, recentPos] = await Promise.all([
db.purchaseOrder.count({
where: { submitterId: userId, status: { in: ["DRAFT", "SUBMITTED", "MGR_REVIEW", "VENDOR_ID_PENDING", "EDITS_REQUESTED", "PARTIALLY_CLOSED", "PARTIALLY_PAID"] } },
}),
db.purchaseOrder.count({
where: { submitterId: userId, status: "MGR_REVIEW" },
}),
db.purchaseOrder.count({
where: { submitterId: userId, status: "CLOSED" },
}),
db.purchaseOrder.findMany({
where: { submitterId: userId },
orderBy: { updatedAt: "desc" },
take: 8,
select: { id: true, poNumber: true, title: true, status: true, totalAmount: true, updatedAt: true },
}),
]);
return (
Dashboard
{recentPos.length > 0 && (
Recent Orders
| PO Number |
Title |
Status |
Amount |
Updated |
{recentPos.map((po) => (
|
{po.poNumber}
|
{po.title} |
|
{formatCurrency(Number(po.totalAmount))} |
{formatDate(po.updatedAt)} |
))}
)}
);
}
async function ManagerDashboard() {
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const twelveMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 11, 1);
const approvedStatuses = ["MGR_APPROVED", "SENT_FOR_PAYMENT", "PARTIALLY_PAID", "PAID_DELIVERED", "CLOSED"] as const;
const [awaitingCount, approvedThisMonth, totalSpendResult, recentApproved, vesselBreakdown, monthlyPos] = await Promise.all([
db.purchaseOrder.count({ where: { status: "MGR_REVIEW" } }),
db.purchaseOrder.count({ where: { status: "MGR_APPROVED", approvedAt: { gte: startOfMonth } } }),
db.purchaseOrder.aggregate({
_sum: { totalAmount: true },
where: { status: { in: [...approvedStatuses] } },
}),
db.purchaseOrder.findMany({
where: { status: { in: ["MGR_APPROVED", "SENT_FOR_PAYMENT", "PARTIALLY_PAID", "PAID_DELIVERED"] } },
orderBy: { approvedAt: "desc" },
take: 8,
select: { id: true, poNumber: true, title: true, status: true, totalAmount: true, approvedAt: true, vessel: { select: { name: true } } },
}),
db.purchaseOrder.groupBy({
by: ["vesselId"],
_sum: { totalAmount: true },
where: { status: { in: [...approvedStatuses] } },
orderBy: { _sum: { totalAmount: "desc" } },
take: 5,
}),
db.purchaseOrder.findMany({
where: { status: { in: [...approvedStatuses] }, approvedAt: { gte: twelveMonthsAgo } },
select: { totalAmount: true, approvedAt: true },
}),
]);
const vesselIds = vesselBreakdown.map((r) => r.vesselId);
const vessels = await db.vessel.findMany({ where: { id: { in: vesselIds } }, select: { id: true, name: true } });
const vesselMap = Object.fromEntries(vessels.map((v) => [v.id, v.name]));
const totalSpend = Number(totalSpendResult._sum.totalAmount ?? 0);
// Build monthly series for last 12 months
const monthlyMap: Record = {};
for (let i = 11; i >= 0; i--) {
const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
monthlyMap[key] = 0;
}
for (const po of monthlyPos) {
if (!po.approvedAt) continue;
const key = `${po.approvedAt.getFullYear()}-${String(po.approvedAt.getMonth() + 1).padStart(2, "0")}`;
if (key in monthlyMap) monthlyMap[key] += Number(po.totalAmount);
}
const monthData = Object.entries(monthlyMap).map(([key, amount]) => {
const [year, month] = key.split("-");
const label = new Date(Number(year), Number(month) - 1, 1).toLocaleString("en", { month: "short", year: "2-digit" });
return { month: label, amount };
});
const vesselChartData = vesselBreakdown.map((row) => ({
name: vesselMap[row.vesselId] ?? "Unknown",
amount: Number(row._sum.totalAmount ?? 0),
}));
return (
Dashboard
{/* Recent approved POs */}
{recentApproved.length > 0 && (
Recent Approved Orders
View all →
| PO |
Title |
Cost Centre |
Status |
Amount |
Approved |
{recentApproved.map((po) => (
|
{po.poNumber}
|
{po.title} |
{po.vessel.name} |
|
{formatCurrency(Number(po.totalAmount))} |
{po.approvedAt ? formatDate(po.approvedAt) : "—"} |
))}
)}
);
}
async function AccountsDashboard() {
const [queueCount, queueValueResult] = await Promise.all([
db.purchaseOrder.count({ where: { status: "MGR_APPROVED" } }),
db.purchaseOrder.aggregate({
_sum: { totalAmount: true },
where: { status: "MGR_APPROVED" },
}),
]);
const queueValue = Number(queueValueResult._sum.totalAmount ?? 0);
return (
);
}
async function GenericDashboard() {
const total = await db.purchaseOrder.count();
return (
);
}