# Order tracking screen

> Live order status: the arrival estimate with minutes that roll as they count down, a timeline whose line fills into each step as the order moves on (finished steps draw a check, the current one breathes), the courier with call and message buttons, and the items. Delivery lands a success check and asks for a rating.

- Type: Component (screens)
- Access: Pro
- Page: https://goodui.dev/native/components/order-tracking-screen
- Markdown: https://goodui.dev/native/components/order-tracking-screen.md
- Registry item: https://goodui.dev/native/r/order-tracking-screen.json
- Dependencies: react-native-reanimated, react-native-svg
- Keywords: react native order tracking, delivery status timeline, expo food delivery screen, courier card call message, eta countdown, order progress steps, rate your courier

## When to use

- After checkout in a shop, grocery or food delivery app: where the order is and when it arrives.
- Any process with a few ordered steps people wait on: a repair, a pickup, a ride on its way.

## When not to use

- A live map with the courier's position: put your map component above this screen's content; this screen has no map.
- Past orders: list them with list-row and open a static receipt.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add @goodui-native-pro/order-tracking-screen
npx expo install --fix
```

Pro: add `"@goodui-native-pro": { "url": "https://goodui.dev/native/r/pro/{name}.json", "headers": { "Authorization": "Bearer ${GOODUI_LICENSE_KEY}" } }` to the `registries` of components.json and put your license key in .env.local.

The component lands in `components/goodui-native/order-tracking-screen/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs avatar, button, icon-button, list-row, locale, rating, rolling-number, success-check.

### Setup

- Wrap the app in GestureHandlerRootView and ThemeProvider.

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
// app/orders/[id].tsx
import { Linking } from "react-native";
import { Stack, router, useLocalSearchParams } from "expo-router";
import { OrderTrackingScreen } from "@/components/goodui-native/order-tracking-screen/order-tracking-screen";
import { api, useOrder } from "@/lib/orders";

export default function OrderRoute() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const order = useOrder(id); // live: re-renders as your server pushes status updates
  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />
      <OrderTrackingScreen
        orderNumber={order.number}
        steps={order.steps} // [{ key, title, description, time }]
        currentStep={order.stepIndex} // steps.length when delivered
        eta={new Date(order.eta)}
        courier={order.courier} // { name, avatar, vehicle, rating }
        items={order.items}
        total={order.total}
        currency="EUR"
        onCall={() => Linking.openURL(`tel:${order.courier.phone}`)}
        onMessage={() => router.push(`/orders/${id}/chat`)}
        unreadMessages={order.unread}
        onRateCourier={(stars) => api.rateCourier(id, stars)}
        onHelp={() => router.push(`/help?order=${id}`)}
        onBack={() => router.back()}
      />
    </>
  );
}
```

## Examples

### On its own, on its way

```tsx
<OrderTrackingScreen />
```

### Delivered, asking for a rating

```tsx
<OrderTrackingScreen currentStep={4} onRateCourier={(stars) => api.rate(stars)} />
```

## API reference

### OrderTrackingScreen

`import { OrderTrackingScreen } from "@/components/goodui-native/order-tracking-screen/order-tracking-screen";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `orderNumber` | `string` | `"PN-48213"` | Order reference shown in the header. |
| `steps` | `OrderStep[]` | `defaultSteps` | The steps, first to last. The last one is delivery. |
| `currentStep` | `number` | `2` | Index of the step in progress (controlled). `steps.length` or more means delivered. |
| `eta` | `Date` | – | Expected arrival. The minutes left count down and roll. |
| `courier` | `OrderCourier` | `defaultCourier` | – |
| `items` | `OrderTrackingItem[]` | `defaultItems` | – |
| `total` | `number` | `408.8` | Order total in `currency`. |
| `currency` | `string` | `"EUR"` | ISO 4217 code. Default "EUR". |
| `onCall` | `() => unknown` | – | Call the courier. Hidden when omitted. |
| `onMessage` | `() => unknown` | – | Message the courier. Hidden when omitted. |
| `unreadMessages` | `number` | – | Unread messages from the courier, shown on the message button. |
| `onHelp` | `() => unknown` | – | "Get help with this order". Hidden when omitted. |
| `onRateCourier` | `(rating: number) => unknown` | – | Rate the courier once delivered. Called with 1 to 5 when a tap or drag ends. |
| `onBack` | `() => void` | – | Back button. Hidden when omitted. |
| `locale` | `string` | – | BCP 47 locale for times and amounts. Defaults to the device locale. |
| `labels` | `Partial<OrderTrackingScreenLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- The header reads 'Order PN-48213' with the item count and total under it.
- The timeline is a list named 'Order progress'. On native each step is one element read as 'Packed, done, 14:02, At the Chiado store, step 2 of 4'; on the web the visible text is read with the state as visually hidden text.
- A step change is announced with the new step's title and description; delivery is announced.
- The minutes left are read as plain text ('12 minutes'); 'Expected by 14:35' is visible text.
- Call and message are labelled icon buttons ('Call Leo Martins', 'Message Leo Martins, 1 unread'). The delivery rating is adjustable with its labels (Poor to Great).

## Motion

- When currentStep moves on, the line under the finished step fills down to the next dot on the smooth spring, the finished dot fills and draws its check, and the new current dot springs in (bouncy) and starts breathing.
- The minutes left roll down as the estimate counts down (checked every 15 s).
- Delivered: the success check springs in, draws, and its ring pulses; the rating stars pop as you choose.
- Reduced motion: lines and dots change at once, no breathing, the check appears complete without drawing, digits change in place.

## Haptics

- tap on call and message (IconButton)
- success when the delivery check lands (SuccessCheck)
- select for each star while rating (Rating)
- tap on Get help (Button)

## Performance

- Each step owns two shared values (line fill, dot) and the current one a repeating halo, all on the UI thread.
- One interval re-renders the screen every 15 s to update the minutes; it stops when the screen unmounts.

## Notes for AI

- Drive currentStep from your server: the index of the step in progress; steps.length (or more) means delivered. Steps before it show their time.
- Pass eta as a Date; the screen counts the minutes itself and never shows less than 1. Without eta it uses 14 minutes from when it opened, which is only for previews.
- Buttons appear only for the callbacks you pass: onCall, onMessage, onHelp, onBack; onRateCourier shows the rating once delivered.
- Render it full-bleed with the navigator header hidden (headerShown: false); it handles the safe areas itself.

## Related

- [Checkout screen](https://goodui.dev/native/components/checkout-screen.md): The last step before paying: delivery address and payment method pickers, delivery options, the order summary with totals that roll when the delivery changes, and slide to pay in thumb reach. Paying covers the screen with a success check and confetti, then hands over through onDone.
- [Success check](https://goodui.dev/native/components/success-check.md): A success or error moment: the circle springs in, the check draws itself while a ring pulses out and the title rises in; the error variant draws a cross and shakes once. Inline or fullscreen, optionally with confetti.
- [Avatar](https://goodui.dev/native/components/avatar.md): A photo that fades in over initials on a color picked from the name, with a presence dot and a story ring whose accent arc sweeps in when there is something new and away once seen; AvatarGroup stacks people with a +N counter and fans out on tap.
- [Rating](https://goodui.dev/native/components/rating.md): Stars (or any symbol) you tap or drag across: the fill sweeps from the old rating to the new one and every symbol it crosses pops on its own beat; half steps optional, and a read-only variant shows exact fractions with a value and a count.
- [Rolling number](https://goodui.dev/native/components/rolling-number.md): A number whose digits roll in the direction of change, with digits that open and close in place and currency signs that glide instead of jumping.
- [List row](https://goodui.dev/native/components/list-row.md): Settings and navigation cells with a token-colored icon tile, title, subtitle and a trailing value, switch, badge, check or chevron, grouped in inset sections with headers and footers. On touch down the highlight floods in, the tile sinks and the chevron leans forward; on release the highlight lingers and fades.

## Guidance for AI tools

Order tracking screen: Live order status: the arrival estimate with minutes that roll as they count down, a timeline whose line fills into each step as the order moves on (finished steps draw a check, the current one breathes), the courier with call and message buttons, and the items. Delivery lands a success check and asks for a rating. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
