import { permissions } from "@mrp/shared"; import type { ProjectDetailDto } from "@mrp/shared/dist/projects/types.js"; import type { SalesOrderPlanningDto } from "@mrp/shared/dist/sales/types.js"; import type { WorkOrderSummaryDto } from "@mrp/shared"; import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; import { FileAttachmentsPanel } from "../../components/FileAttachmentsPanel"; import { useAuth } from "../../auth/AuthProvider"; import { api, ApiError } from "../../lib/api"; import { ProjectPriorityBadge } from "./ProjectPriorityBadge"; import { ProjectStatusBadge } from "./ProjectStatusBadge"; export function ProjectDetailPage() { const { token, user } = useAuth(); const { projectId } = useParams(); const [project, setProject] = useState(null); const [workOrders, setWorkOrders] = useState([]); const [planning, setPlanning] = useState(null); const [status, setStatus] = useState("Loading project..."); const canManage = user?.permissions.includes(permissions.projectsWrite) ?? false; useEffect(() => { if (!token || !projectId) { return; } api.getProject(token, projectId) .then((nextProject) => { setProject(nextProject); setStatus("Project loaded."); if (nextProject.salesOrderId) { api.getSalesOrderPlanning(token, nextProject.salesOrderId).then(setPlanning).catch(() => setPlanning(null)); } else { setPlanning(null); } return api.getWorkOrders(token, { projectId: nextProject.id }); }) .then((nextWorkOrders) => setWorkOrders(nextWorkOrders)) .catch((error: unknown) => { const message = error instanceof ApiError ? error.message : "Unable to load project."; setStatus(message); }); }, [projectId, token]); if (!project) { return
{status}
; } return (

Project

{project.projectNumber}

{project.name}

Back to projects {canManage ? Edit project : null}

Customer

{project.customerName}

Owner

{project.ownerName || "Unassigned"}

Due Date

{project.dueDate ? new Date(project.dueDate).toLocaleDateString() : "Not set"}

Created

{new Date(project.createdAt).toLocaleDateString()}

Customer Linkage

Account
{project.customerName}
Email
{project.customerEmail}
Phone
{project.customerPhone}

Program Notes

{project.notes || "No project notes recorded."}

Commercial + Delivery Links

Quote
{project.salesQuoteNumber ? {project.salesQuoteNumber} : "Not linked"}
Sales Order
{project.salesOrderNumber ? {project.salesOrderNumber} : "Not linked"}
Shipment
{project.shipmentNumber ? {project.shipmentNumber} : "Not linked"}
{planning ? (

Material Readiness

Build Qty

{planning.summary.totalBuildQuantity}

Buy Qty

{planning.summary.totalPurchaseQuantity}

Uncovered Qty

{planning.summary.totalUncoveredQuantity}

Shortage Items

{planning.summary.uncoveredItemCount}
{planning.items .filter((item) => item.recommendedBuildQuantity > 0 || item.recommendedPurchaseQuantity > 0 || item.uncoveredQuantity > 0) .slice(0, 8) .map((item) => (
{item.itemSku}
{item.itemName}
Build {item.recommendedBuildQuantity} · Buy {item.recommendedPurchaseQuantity} · Uncovered {item.uncoveredQuantity}
))}
) : null}

Manufacturing Links

Work orders already linked to this project.

{canManage ? ( New work order ) : null}
{workOrders.length === 0 ? (
No work orders are linked to this project yet.
) : (
{workOrders.map((workOrder) => (
{workOrder.workOrderNumber}
{workOrder.itemSku} · {workOrder.completedQuantity}/{workOrder.quantity} complete
{workOrder.status.replace("_", " ")}
))}
)}
{status}
); }