# Booking details screen

> One appointment in full: status badge and reference, the day and time with how far away it is, the professional, the services and total, a map card with Directions and Call, Add to calendar, Reschedule, and a hold-to-cancel that names the free cancellation window.

- Type: Component (screens)
- Access: Pro
- Page: https://goodui.dev/native/components/booking-details-screen
- Markdown: https://goodui.dev/native/components/booking-details-screen.md
- Registry item: https://goodui.dev/native/r/booking-details-screen.json
- Dependencies: react-native-reanimated, react-native-svg
- Keywords: react native appointment details, booking details screen, reservation detail page, directions to salon, cancel booking hold, add appointment to calendar, expo booking detail

## When to use

- Opening a single appointment from a list or a notification.
- Showing where to go, with directions and a call button, and what was booked.
- Letting the client cancel within a policy without a confirmation modal.

## When not to use

- A list of appointments: use appointments-screen.
- Reviewing a booking before it exists: use booking-confirm-screen.
- Order tracking for deliveries: use order-tracking-screen.

## 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/booking-details-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/booking-details-screen/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs avatar, badge, button, hold-to-confirm, large-title-header, list-row, locale, rating, service-picker-screen.

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
import { router, Stack, useLocalSearchParams } from "expo-router";
import { Linking } from "react-native";
import { BookingDetailsScreen } from "@/components/goodui-native/booking-details-screen/booking-details-screen";
import { api } from "@/lib/api";
import { addToCalendar } from "@/lib/calendar";
import { useAppointment } from "@/lib/booking"; // your data, an Appointment

export default function AppointmentRoute() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const appointment = useAppointment(id);
  if (!appointment) return null;
  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />
      <BookingDetailsScreen
        appointment={appointment}
        onBack={() => router.back()}
        onDirections={(a) => {
          const c = a.business.coordinates;
          Linking.openURL(c ? `https://maps.google.com/?daddr=${c.lat},${c.lng}` : `https://maps.google.com/?q=${encodeURIComponent(a.business.address)}`);
        }}
        onCall={(phone) => Linking.openURL(`tel:${phone.replace(/\s/g, "")}`)}
        onAddToCalendar={(a) => addToCalendar(a)}
        onReschedule={(a) => router.push({ pathname: "/book/time", params: { reschedule: a.id } })}
        onCancel={(a) => api.cancel(a.id)}
        onBookAgain={(a) => router.push({ pathname: "/book", params: { again: a.id } })}
      />
    </>
  );
}
```

## Examples

### Sample appointment, no props

```tsx
<BookingDetailsScreen />
```

### With a static map image

```tsx
<BookingDetailsScreen appointment={appointment} mapImage={{ uri: staticMapUrl }} />
```

## API reference

### BookingDetailsScreen

`import { BookingDetailsScreen } from "@/components/goodui-native/booking-details-screen/booking-details-screen";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `appointment` | `Appointment` | – | The appointment to show. |
| `mapImage` | `ImageSourcePropType` | – | Image for the map card, for example a static map of the address. A drawn street map shows without it. |
| `onBack` | `() => void` | – | Shows a back button in the bar. |
| `onDirections` | `(appointment: Appointment) => void` | – | "Directions" on the location card, for example to open the maps app at `business.coordinates`. |
| `onCall` | `(phone: string) => void` | – | "Call" on the location card, with the business phone number. Shown when the business has one. |
| `onAddToCalendar` | `(appointment: Appointment) => unknown` | – | "Add to calendar". Return a promise to show pending, then "Added". |
| `onReschedule` | `(appointment: Appointment) => void` | – | "Reschedule" on an upcoming appointment. |
| `onCancel` | `(appointment: Appointment) => unknown` | – | Hold to cancel on an upcoming appointment. Return a promise: the control spins until it settles, then the status turns to Cancelled. Hidden when omitted. |
| `onBookAgain` | `(appointment: Appointment) => void` | – | "Book again" on a past or cancelled appointment. |
| `title` | `string` | – | Bar title. Default "Appointment". Same as `labels.title`. |
| `locale` | `string` | – | BCP 47 locale for dates, times and prices. Defaults to the device locale. |
| `hour12` | `boolean` | – | Force a 12 or 24 hour clock. Defaults to the locale's. |
| `now` | `Date` | – | The current time, for "in 2 days" and the free cancellation window. Default now. |
| `labels` | `Partial<BookingDetailsScreenLabels>` | – | 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 day is a header; the large title collapses into the bar with a labelled back button (LargeTitleScrollView).
- The map card is one image named after the address; the avatar is hidden because the name is written next to it.
- Services are list rows with name, length and price; the total is its own row.
- Hold to cancel is the kit's HoldToConfirm: a button with the policy as its hint, announced when done.

## Motion

- Hold to cancel fills like ink while held and draws a check; then the status badge turns to Cancelled with a fade and the actions give way to Book again.
- The large title collapses into the bar on scroll; Add to calendar gathers into a spinner and opens into Added.
- Reduced motion: the components follow their own reduced-motion rules; the status and the actions crossfade.

## Haptics

- select at each quarter of the hold, warning at its end, confirm when cancelled or error when onCancel rejects (HoldToConfirm)
- tap on buttons, then success or error for promises (Button)

## Performance

- Static content in one ScrollView; the drawn map is a single SVG with theme colors, no map SDK.

## Notes for AI

- appointment is an Appointment from booking-types; status, start, items, staff and business drive everything on screen.
- Every action appears only when its callback is passed. onCancel and onAddToCalendar may return promises; the screen marks the appointment cancelled locally when onCancel resolves.
- Pass mapImage for a real static map; without it a themed street drawing with a pin shows.
- The free cancellation window comes from business.cancellationHours; the hint switches to the late fee text inside it.
- Hide the navigator header (headerShown: false).

## Related

- [Appointments screen](https://goodui.dev/native/components/appointments-screen.md): A client's bookings in Upcoming and Past tabs: date-tile cards with status, time, professional and place. Swipe a card for Reschedule or Cancel; cancelling asks in an alert that spins while the request runs, then the card slides out of Upcoming and the tab count drops.
- [Hold to confirm](https://goodui.dev/native/components/hold-to-confirm.md): Confirms an irreversible action by holding: ink fills from the leading edge, the label inverts where the ink passes, and haptics tick at every quarter.
- [Large title header](https://goodui.dev/native/components/large-title-header.md): An iOS large title that collapses into a compact bar as the content scrolls: the titles cross-fade, the bar fades in, the title stretches when pulled past the top and a half-finished collapse settles on either state.
- [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.
- [Badge](https://goodui.dev/native/components/badge.md): A count, dot or status badge that springs in when it appears, pops when its value changes, caps at 99+ and shrinks away at zero; BadgeAnchor pins it to an icon or avatar.

## Guidance for AI tools

Booking details screen: One appointment in full: status badge and reference, the day and time with how far away it is, the professional, the services and total, a map card with Directions and Call, Add to calendar, Reschedule, and a hold-to-cancel that names the free cancellation window. 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
