-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add delivery-brief route with milestone summaries, checkpoint cards, and follow-up notes #250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
iamasx
wants to merge
2
commits into
main
Choose a base branch
from
feat/issue-245
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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", | ||
| }; | ||
|
|
||
| // 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; | ||
| }; | ||
|
|
||
|
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
64
src/app/delivery-brief/_components/follow-up-notes-rail.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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", | ||
| }, | ||
| ]; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.