# Delivery Tracker

> A customer-facing order tracker - five delivery steps with times, an ETA, the courier with call and message actions, a map slot, and cancelled or failed outcomes.

Source: https://docs.nasaqui.com/components/delivery-tracker

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/delivery-tracker.json
```

Shows where an order is: placed, assigned, picked up, on the way, delivered. It adds an ETA, the courier, and any
cancelled or failed reason. Pass a `MapView` in the `map` slot for live location.

## When to use

- A customer tracking page or link.
- An order detail panel in an ops console.

## When not to use

- A generic event history: use [`Timeline`](https://docs.nasaqui.com/components/timeline).
- Store order lifecycle with payment steps: use [`StoreOrderTimeline`](https://docs.nasaqui.com/components/store-order-timeline).

## Import

```tsx
import { DeliveryTracker } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
<DeliveryTracker orderNumber="1042" status="on-the-way" etaSeconds={540} courier={{ name: "Omar", nameAr: "عمر", phone: "+970591234567" }} />
```

## Anatomy

```
DeliveryTracker  data-slot="delivery-tracker"  data-status
├─ header: order number, ETA
├─ map slot
├─ courier row: call, message
├─ steps list  data-slot="delivery-steps"
└─ outcome note (cancelled / failed)
```

## API

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `status` | `DeliveryOrderStatus` | required | `placed`, `assigned`, `picked-up`, `on-the-way`, `delivered`, `cancelled`, `failed`. |
| `reachedBefore` | `DeliveryStep` | none | For cancelled or failed: the last step reached. |
| `times` | `DeliveryTrackerTimes` | none | Time per step. |
| `orderNumber` | `string` | none | Shown in the header. |
| `etaSeconds` / `etaAt` | `number` / date | none | Time left, or the arrival moment. |
| `courier` | `DeliveryCourier` | none | `name`, `nameAr`, `avatarSrc`, `vehicle`, `phone`. |
| `onCall` / `onMessage` | `() => void` | none | Actions; a `phone` renders a `tel:` link. |
| `reason` / `reasonAr` | `string` | none | Why it was cancelled or failed. |
| `map` | `ReactNode` | none | Map slot. |
| `locale` / `labels` | `"en" \| "ar"` / partial strings | context | Language and overrides. |

## Examples

Lab stories cover each status, a live map and Arabic.

## Accessibility

The steps are an ordered list; the current step has `aria-current="step"`. The ETA is announced politely. Action buttons
are native buttons or links.

## RTL & i18n

The step rail mirrors in RTL. Arabic copy is built in; the map canvas stays LTR.

## Styling & tokens

Uses `--status-success`, `--status-danger` and `--brand`. Target `[data-status]`.

## Do / Don't

- Do show the reason for a failed delivery.
- Don't show an ETA after delivery.

## Related

[`CourierCard`](https://docs.nasaqui.com/components/courier-card), [`MapView`](https://docs.nasaqui.com/components/map-view), [`Timeline`](https://docs.nasaqui.com/components/timeline).

## Lab

https://docs.nasaqui.com/?path=/docs/components-delivery-delivery-tracker--docs

## Code

### React

```tsx
<DeliveryTracker orderNumber="1042" status="on-the-way" etaSeconds={540} courier={{ name: "Omar", nameAr: "عمر", phone: "+970591234567" }} />
```

### shadcn

```tsx
<DeliveryTracker orderNumber="1042" status="on-the-way" etaSeconds={540} courier={{ name: "Omar", nameAr: "عمر", phone: "+970591234567" }} />
```

### Vue

```vue
<script setup lang="ts">
import { NqDeliveryTracker } from "@fadymondy/nasaq/vue";
</script>

<template>
  <NqDeliveryTracker order-number="1042" status="on-the-way" :eta-seconds="540" :courier="{ name: 'Omar', nameAr: 'عمر', phone: '+970591234567' }" />
</template>
```

### Blade

```blade
<x-nq::delivery-tracker order-number="1042" status="on-the-way" :eta-seconds="540" :courier="['name' => 'Omar', 'nameAr' => 'عمر', 'phone' => '+970591234567']" />
```

### HTML + Alpine

```html
<section data-slot="delivery-tracker" data-status="on-the-way" aria-label="Order tracking"
    class="flex flex-col gap-4 rounded-card border border-border bg-card p-4 sm:p-5">
    <header class="flex flex-wrap items-start justify-between gap-3">
        <div class="flex min-w-0 flex-col gap-1">
                            <span class="text-caption text-muted-foreground">Order <bdi dir="ltr" class="tabular-nums">1042</bdi></span>
                        <h2 class="text-h3 text-foreground">On the way</h2>
        </div>
        <div class="flex flex-col items-end gap-1">
            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-nq-brand/40 bg-[color-mix(in_oklab,var(--nq-brand)_14%,transparent)] text-foreground">On the way</span>
                            <span data-slot="delivery-eta" class="text-body-sm text-foreground">Arriving in <bdi class="tabular-nums font-medium">9 min</bdi></span>
                    </div>
    </header>
    <ol role="list" aria-label="Delivery progress" data-slot="delivery-steps" class="flex flex-col">
                                <li data-step="placed" data-state="done"  class="flex gap-3">
                <span class="flex flex-col items-center">
                    <span class="flex size-8 shrink-0 items-center justify-center rounded-full border-2 [&_svg]:size-4 border-primary bg-primary text-primary-foreground">
                                                    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg>                                            </span>
                                            <span aria-hidden="true" class="my-1 min-h-6 w-0.5 flex-1 rounded-full bg-primary"></span>
                                    </span>
                <div class="flex min-w-0 flex-1 flex-col pt-1 pb-4">
                    <span class="text-label text-foreground">Order placed<span class="sr-only"> (done)</span></span>
                                    </div>
            </li>
                                <li data-step="assigned" data-state="done"  class="flex gap-3">
                <span class="flex flex-col items-center">
                    <span class="flex size-8 shrink-0 items-center justify-center rounded-full border-2 [&_svg]:size-4 border-primary bg-primary text-primary-foreground">
                                                    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg>                                            </span>
                                            <span aria-hidden="true" class="my-1 min-h-6 w-0.5 flex-1 rounded-full bg-primary"></span>
                                    </span>
                <div class="flex min-w-0 flex-1 flex-col pt-1 pb-4">
                    <span class="text-label text-foreground">Courier assigned<span class="sr-only"> (done)</span></span>
                                    </div>
            </li>
                                <li data-step="picked-up" data-state="done"  class="flex gap-3">
                <span class="flex flex-col items-center">
                    <span class="flex size-8 shrink-0 items-center justify-center rounded-full border-2 [&_svg]:size-4 border-primary bg-primary text-primary-foreground">
                                                    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg>                                            </span>
                                            <span aria-hidden="true" class="my-1 min-h-6 w-0.5 flex-1 rounded-full bg-primary"></span>
                                    </span>
                <div class="flex min-w-0 flex-1 flex-col pt-1 pb-4">
                    <span class="text-label text-foreground">Picked up<span class="sr-only"> (done)</span></span>
                                    </div>
            </li>
                                <li data-step="on-the-way" data-state="current"  aria-current="step"  class="flex gap-3">
                <span class="flex flex-col items-center">
                    <span class="flex size-8 shrink-0 items-center justify-center rounded-full border-2 [&_svg]:size-4 border-primary bg-card text-primary ring-4 ring-primary/20">
                                                    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="18.5" cy="17.5" r="3.5"/>
  <circle cx="5.5" cy="17.5" r="3.5"/>
  <circle cx="15" cy="5" r="1"/>
  <path d="M12 17.5V14l-3-3 4-3 2 3h2"/>
</svg>                                            </span>
                                            <span aria-hidden="true" class="my-1 min-h-6 w-0.5 flex-1 rounded-full bg-nq-line"></span>
                                    </span>
                <div class="flex min-w-0 flex-1 flex-col pt-1 pb-4">
                    <span class="text-label text-foreground">On the way<span class="sr-only"> (current step)</span></span>
                                    </div>
            </li>
                                <li data-step="delivered" data-state="upcoming"  class="flex gap-3">
                <span class="flex flex-col items-center">
                    <span class="flex size-8 shrink-0 items-center justify-center rounded-full border-2 [&_svg]:size-4 border-nq-line-strong bg-card text-muted-foreground">
                                                    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg>                                            </span>
                                    </span>
                <div class="flex min-w-0 flex-1 flex-col pt-1 pb-0">
                    <span class="text-label text-muted-foreground">Delivered<span class="sr-only"> (not yet)</span></span>
                                    </div>
            </li>
            </ol>
            <div data-slot="delivery-courier" class="flex flex-wrap items-center gap-3 rounded-control border border-border bg-secondary p-3">
            <span data-slot="avatar" x-data="nqAvatar(0)"
    class="inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-10 text-label rounded-full">
                    <span data-slot="avatar-fallback" class="flex size-full items-center justify-center" x-bind="fallback"
             role="img" aria-label="Omar" >O</span>
    </span>
            <div class="flex min-w-0 flex-1 flex-col">
                <span class="text-caption text-muted-foreground">Your courier</span>
                <bdi dir="auto" class="truncate text-label text-foreground">Omar</bdi>
                            </div>
            <div class="flex items-center gap-2">
                                                    <a data-slot="button"
     href="tel:+970591234567"                         class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384"/>
</svg>                        Call</a>
                            </div>
        </div>
    </section>
```
