Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/app/delivery-brief/_components/checkpoint-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { Checkpoint } from "../_data/delivery-brief-data";
import styles from "../delivery-brief.module.css";

const severityLabels: Record<Checkpoint["severity"], string> = {
normal: "Normal",
delayed: "Delayed",
critical: "Critical",
};

const severityBadgeStyles: Record<Checkpoint["severity"], string> = {
normal: "border-emerald-300/20 bg-emerald-300/10 text-emerald-50",
delayed: "border-amber-300/20 bg-amber-300/10 text-amber-50",
critical: "border-rose-300/20 bg-rose-300/10 text-rose-50",
};

Comment thread
iamasx marked this conversation as resolved.
// Maps each severity level to the corresponding CSS module class for card border styling
const severitySurfaceStyles: Record<Checkpoint["severity"], string> = {
normal: styles.checkpointNormal,
delayed: styles.checkpointDelayed,
critical: styles.checkpointCritical,
};

type CheckpointCardProps = {
checkpoint: Checkpoint;
};

Comment thread
iamasx marked this conversation as resolved.
// Renders a single checkpoint with location, timestamp, carrier, severity badge, and detail
export function CheckpointCard({ checkpoint }: CheckpointCardProps) {
return (
<article
className={`${styles.checkpointCard} ${severitySurfaceStyles[checkpoint.severity]} rounded-[1.7rem] border p-6`}
role="listitem"
>
<div className="flex flex-wrap items-start justify-between gap-3">
<div className="space-y-1">
<h3 className="text-lg font-semibold tracking-tight text-white">
{checkpoint.location}
</h3>
<p className="text-sm text-slate-300">{checkpoint.timestamp}</p>
</div>
<span
className={`${styles.statusBadge} inline-flex rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] ${severityBadgeStyles[checkpoint.severity]}`}
>
{severityLabels[checkpoint.severity]}
</span>
</div>

<div className="mt-4 rounded-2xl border border-white/8 bg-white/5 px-4 py-3">
<p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">
Carrier
</p>
<p className="mt-1 text-sm font-medium text-slate-100">
{checkpoint.carrier}
</p>
</div>

<p className="mt-4 text-sm leading-6 text-slate-300">
{checkpoint.detail}
</p>
</article>
);
}
64 changes: 64 additions & 0 deletions src/app/delivery-brief/_components/follow-up-notes-rail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { FollowUpNote } from "../_data/delivery-brief-data";
import styles from "../delivery-brief.module.css";

const priorityLabels: Record<FollowUpNote["priority"], string> = {
info: "Info",
action: "Action",
warning: "Warning",
};

const priorityBadgeStyles: Record<FollowUpNote["priority"], string> = {
info: "border-cyan-300/20 bg-cyan-300/10 text-cyan-50",
action: "border-emerald-300/20 bg-emerald-300/10 text-emerald-50",
warning: "border-amber-300/20 bg-amber-300/10 text-amber-50",
};

type FollowUpNotesRailProps = {
notes: FollowUpNote[];
};

export function FollowUpNotesRail({ notes }: FollowUpNotesRailProps) {
return (
<section aria-label="Follow-up notes" className="space-y-5">
<div className="space-y-2">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-slate-400">
Team notes
</p>
<h2 className="text-3xl font-semibold tracking-tight text-white sm:text-4xl">
Follow-up notes
</h2>
<p className="max-w-2xl text-sm leading-6 text-slate-300">
Action items, warnings, and status updates from the delivery team.
Each note is tied to a team member and timestamped.
</p>
</div>

<div className="space-y-4" role="list" aria-label="Follow-up notes list">
{notes.map((note) => (
<article
key={note.id}
className={`${styles.noteCard} rounded-[1.5rem] border border-white/10 p-5`}
role="listitem"
>
<div className="flex flex-wrap items-start justify-between gap-3">
<div className="space-y-1">
<p className="text-sm font-semibold text-white">
{note.author}
</p>
<p className="text-xs text-slate-400">{note.timestamp}</p>
</div>
<span
className={`${styles.statusBadge} inline-flex rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] ${priorityBadgeStyles[note.priority]}`}
>
{priorityLabels[note.priority]}
</span>
</div>
<p className="mt-3 text-sm leading-6 text-slate-300">
{note.body}
</p>
</article>
))}
</div>
</section>
);
}
47 changes: 47 additions & 0 deletions src/app/delivery-brief/_components/milestone-summary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Milestone } from "../_data/delivery-brief-data";
import styles from "../delivery-brief.module.css";

const statusLabels: Record<Milestone["status"], string> = {
completed: "Completed",
"in-progress": "In Progress",
upcoming: "Upcoming",
};

const statusBadgeStyles: Record<Milestone["status"], string> = {
completed: "border-emerald-300/20 bg-emerald-300/10 text-emerald-50",
"in-progress": "border-amber-300/20 bg-amber-300/10 text-amber-50",
upcoming: "border-slate-300/20 bg-slate-300/10 text-slate-200",
};

type MilestoneSummaryCardProps = {
milestone: Milestone;
};

export function MilestoneSummaryCard({ milestone }: MilestoneSummaryCardProps) {
return (
<article
className={`${styles.milestoneCard} ${styles[milestone.status === "completed" ? "milestoneCompleted" : milestone.status === "in-progress" ? "milestoneInProgress" : "milestoneUpcoming"]} rounded-[1.7rem] border p-6`}
role="listitem"
>
<div className="flex flex-wrap items-start justify-between gap-3">
<div className="space-y-1">
<h3 className="text-lg font-semibold tracking-tight text-white">
{milestone.label}
</h3>
{milestone.completedAt && (
<p className="text-sm text-slate-300">{milestone.completedAt}</p>
)}
</div>
<span
className={`${styles.statusBadge} inline-flex rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] ${statusBadgeStyles[milestone.status]}`}
>
{statusLabels[milestone.status]}
</span>
</div>

<p className="mt-4 text-sm leading-6 text-slate-300">
{milestone.summary}
</p>
</article>
);
}
205 changes: 205 additions & 0 deletions src/app/delivery-brief/_data/delivery-brief-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
export type MilestoneStatus = "completed" | "in-progress" | "upcoming";
export type CheckpointSeverity = "normal" | "delayed" | "critical";

export interface DeliveryBriefOverview {
eyebrow: string;
title: string;
description: string;
shipmentId: string;
origin: string;
destination: string;
}

export interface DeliveryStat {
label: string;
value: string;
detail: string;
}

export interface Milestone {
id: string;
label: string;
status: MilestoneStatus;
completedAt: string | null;
summary: string;
}

export interface Checkpoint {
id: string;
location: string;
timestamp: string;
severity: CheckpointSeverity;
carrier: string;
detail: string;
}

export interface FollowUpNote {
id: string;
author: string;
timestamp: string;
body: string;
priority: "info" | "action" | "warning";
}

export const deliveryBriefOverview: DeliveryBriefOverview = {
eyebrow: "Delivery Brief",
title:
"Track milestones, review checkpoints, and manage follow-up notes for every shipment.",
description:
"A consolidated view of shipment milestones, transit checkpoints, and team follow-up notes that keeps delivery operations transparent from origin to destination.",
shipmentId: "SHP-2026-04887",
origin: "Portland, OR",
destination: "Austin, TX",
};

export const deliveryStats: DeliveryStat[] = [
{
label: "Milestones reached",
value: "3 / 5",
detail:
"Label created, picked up, and in-transit milestones complete. Customs and delivery pending.",
},
{
label: "Checkpoints logged",
value: "6",
detail:
"Six transit checkpoints recorded across three facilities and two carrier hand-offs.",
},
{
label: "Follow-up notes",
value: "4",
detail:
"Two action items, one warning about a delay, and one informational status update.",
},
];

export const milestones: Milestone[] = [
{
id: "ms-label",
label: "Label created",
status: "completed",
completedAt: "2026-04-20 08:15 PDT",
summary:
"Shipping label generated and tracking number assigned. Origin scan expected within 24 hours.",
},
{
id: "ms-pickup",
label: "Picked up",
status: "completed",
completedAt: "2026-04-20 14:30 PDT",
summary:
"Package collected from Portland distribution center by primary carrier. Weight and dimensions verified.",
},
{
id: "ms-transit",
label: "In transit",
status: "in-progress",
completedAt: null,
summary:
"Shipment is moving through the carrier network. Currently at the Denver sorting facility awaiting next-leg dispatch.",
},
{
id: "ms-customs",
label: "Customs clearance",
status: "upcoming",
completedAt: null,
summary:
"Domestic shipment — no customs clearance required. Milestone will auto-complete on arrival at destination hub.",
},
{
id: "ms-delivered",
label: "Delivered",
status: "upcoming",
completedAt: null,
summary:
"Final delivery to the Austin receiving dock. Estimated arrival within two business days.",
},
];

export const checkpoints: Checkpoint[] = [
{
id: "cp-001",
location: "Portland Distribution Center",
timestamp: "2026-04-20 14:30 PDT",
severity: "normal",
carrier: "West Coast Freight",
detail:
"Origin scan completed. Package loaded onto outbound trailer WCF-4421 for eastbound route.",
},
{
id: "cp-002",
location: "Boise Relay Hub",
timestamp: "2026-04-21 03:12 PDT",
severity: "normal",
carrier: "West Coast Freight",
detail:
"Arrival scan at Boise relay hub. Package transferred to cross-dock lane for next-day dispatch.",
},
{
id: "cp-003",
location: "Salt Lake City Sort Facility",
timestamp: "2026-04-21 19:45 PDT",
severity: "normal",
carrier: "Mountain Line Logistics",
detail:
"Carrier hand-off completed. Package sorted into southbound container ML-8803.",
},
{
id: "cp-004",
location: "Denver Sorting Facility",
timestamp: "2026-04-22 11:20 PDT",
severity: "delayed",
carrier: "Mountain Line Logistics",
detail:
"Package held at Denver facility due to trailer capacity constraints. Re-dispatched on next available load.",
},
{
id: "cp-005",
location: "Amarillo Transfer Station",
timestamp: "2026-04-23 06:55 PDT",
severity: "normal",
carrier: "Southern Express",
detail:
"Second carrier hand-off to Southern Express. Package scanned onto trailer SE-2210 bound for Dallas.",
},
{
id: "cp-006",
location: "Dallas Regional Hub",
timestamp: "2026-04-24 09:30 PDT",
severity: "critical",
carrier: "Southern Express",
detail:
"Package flagged for address verification at Dallas hub. Hold placed pending shipper confirmation. Expected resolution within 4 hours.",
},
];

export const followUpNotes: FollowUpNote[] = [
{
id: "fn-001",
author: "L. Nguyen",
timestamp: "2026-04-24 10:15 PDT",
body: "Dallas hub placed a hold on the package for address verification. I've confirmed the Austin delivery address with the customer — releasing the hold now.",
priority: "action",
},
{
id: "fn-002",
author: "R. Kapoor",
timestamp: "2026-04-23 14:20 PDT",
body: "Denver delay added roughly 18 hours to the transit time. Updated the customer-facing ETA from April 24 to April 26.",
priority: "warning",
},
{
id: "fn-003",
author: "T. Alvarez",
timestamp: "2026-04-22 08:45 PDT",
body: "Carrier hand-off from West Coast Freight to Mountain Line Logistics went smoothly. No issues flagged at the Salt Lake sort facility.",
priority: "info",
},
{
id: "fn-004",
author: "M. Brooks",
timestamp: "2026-04-21 16:30 PDT",
body: "Escalate to logistics lead if the Denver hold extends beyond 24 hours. We have a backup route through Albuquerque that can shave a day off transit.",
priority: "action",
},
];
Loading
Loading