# Booking confirm screen

> The last step of a booking flow: a summary card, client details, notes and the cancellation policy, booked with a slide (or a button). The slider spins while the request runs, then the screen gives way to a success check with confetti, Add to calendar and Done.

- Type: Component (screens)
- Access: Pro
- Page: https://goodui.dev/native/components/booking-confirm-screen
- Markdown: https://goodui.dev/native/components/booking-confirm-screen.md
- Registry item: https://goodui.dev/native/r/booking-confirm-screen.json
- Dependencies: react-native-reanimated
- Keywords: react native booking confirmation, appointment review screen, slide to book, booking success screen, add to calendar, cancellation policy checkbox, expo checkout booking

## When to use

- Reviewing and confirming an appointment before it is booked, with the client's contact details.
- Bookings with a cancellation or no-show policy the client must accept.
- Flows that end on a clear booked moment with Add to calendar.

## When not to use

- Paying for physical goods: use checkout-screen.
- Editing an existing appointment: use booking-details-screen with reschedule.
- A single yes or no question: use alert-dialog.

## 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-confirm-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-confirm-screen/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs avatar, button, checkbox, locale, service-picker-screen, success-check, swipe-to-confirm, text-field.

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 } from "expo-router";
import { BookingConfirmScreen } from "@/components/goodui-native/booking-confirm-screen/booking-confirm-screen";
import { api } from "@/lib/api";
import { addToCalendar } from "@/lib/calendar"; // for example with expo-calendar
import { useBookingDraft, useSession } from "@/lib/booking";

export default function ConfirmRoute() {
  const draft = useBookingDraft();
  const { user } = useSession();
  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />
      <BookingConfirmScreen
        business={draft.business}
        items={draft.items}
        staff={draft.staff}
        start={draft.start}
        client={{ name: user?.name, email: user?.email }}
        onBack={() => router.back()}
        onEdit={() => router.back()}
        onConfirm={(details) => api.book({ ...draft.toRequest(), client: details })} // resolves with { reference }
        onAddToCalendar={(appointment) => addToCalendar(appointment)}
        onDone={() => router.dismissAll()}
      />
    </>
  );
}
```

## Examples

### Sample visit, no props

```tsx
<BookingConfirmScreen />
```

### Button instead of a slide, no policy checkbox

```tsx
<BookingConfirmScreen confirmMode="button" requirePolicy={false} onConfirm={book} onDone={close} />
```

## API reference

### BookingConfirmScreen

`import { BookingConfirmScreen } from "@/components/goodui-native/booking-confirm-screen/booking-confirm-screen";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `business` | `BookingBusiness` | `sampleBusiness` | The business; its name, address, currency and cancellation policy show on the screen. |
| `items` | `BookingLineItem[]` | – | What is being booked, services then add-ons. Duration and total are their sums. |
| `staff` | `BookingStaff \| null` | `sampleStaff[0]` | Who it is with. `null` is "Any available". |
| `start` | `Date` | – | Start of the appointment. |
| `client` | `Partial<BookingClient>` | – | Prefill for the client fields, for example from the signed-in account. |
| `onConfirm` | `(details: BookingConfirmDetails) => unknown` | – | Books it. Runs only once the fields are valid and the policy is accepted. Return a promise: while it is pending the slider spins; resolve (optionally with `{ reference }`) to show the success screen, reject with an `Error` whose message is person-facing ("That time was just taken") to shake the slider and show it. |
| `confirmMode` | `"swipe" \| "button"` | `"swipe"` | `swipe` books with a slide (deliberate, no accidental taps); `button` with a primary button. Default `swipe`. |
| `requirePolicy` | `boolean` | `true` | Require ticking the cancellation policy before booking. Default `true`. |
| `onAddToCalendar` | `(appointment: Appointment) => unknown` | – | "Add to calendar" on the success screen, with the booked appointment. Return a promise to show pending and done. |
| `onDone` | `(appointment: Appointment) => void` | – | "Done" on the success screen. Navigate away here. |
| `onEdit` | `() => void` | – | Shows "Change" on the summary card, for going back to the time step. |
| `onBack` | `() => void` | – | Shows a back button in the top bar. Hidden on the success screen. |
| `paymentNote` | `string` | – | How payment works, under the total. Default "Pay at the salon after your visit. No card needed." Same as `labels.paymentNote`. |
| `step` | `BookingStep \| null` | `{ current: 4, total: 4 }` | Step of the booking flow in the top bar. `null` hides it. Default step 4 of 4. |
| `title` | `string` | – | Headline. Default "Review and confirm". 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. |
| `labels` | `Partial<BookingConfirmScreenLabels>` | – | 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

- Fields are TextFields with labels, autocomplete hints and errors that are announced; Next on the keyboard moves through name, email, phone and notes.
- Errors show only after the first attempt and then follow the typing. A failed attempt scrolls the form into view.
- The policy is a checkbox that turns red with a written reason when it is required and unticked.
- The slider is the kit's SwipeToConfirm: a button for screen readers (activating it confirms) with a hint naming the day and time; confirmMode='button' gives a plain button.
- The success screen's check announces its title; the reference and the confirmation email are text.

## Motion

- The slide follows the finger 1:1 and spins while onConfirm runs; a rejection shakes it with the message and it springs back.
- On success the slider shows its check, then the screen crossfades to a success check that springs in, draws its mark and bursts confetti (the one bouncy moment of the flow).
- Reduced motion: the slider and the check follow their own reduced-motion rules (the check fades in complete, confetti shows a static sparkle), the screens crossfade.

## Haptics

- select at the slider's point of no return, confirm or error when the booking settles (SwipeToConfirm)
- celebrate as the success check lands with its confetti (SuccessCheck)
- error when a field error appears (TextField)

## Performance

- Validation is a pure function of the field values; nothing re-renders per keystroke beyond the field itself and its error line.
- On Android the keyboard height pads the scroll view; on iOS the scroll view adjusts its own inset. The bottom bar steps aside while the keyboard is up.

## Notes for AI

- onConfirm(details) runs only when name and email are valid and the policy is ticked. Resolve with { reference } to show it; reject with an Error whose message is person-facing to show it on the slider.
- items are BookingLineItem[] (use lineItemsFor(cart, services, addOns) from booking-types). start is a Date.
- Add to calendar shows only when onAddToCalendar is passed; it receives the booked Appointment.
- Prefill client from the signed-in account; phone is optional.
- Hide the navigator header (headerShown: false).

## Related

- [Booking time screen](https://goodui.dev/native/components/booking-time-screen.md): Step three of a booking flow: a week strip, the day's times grouped by morning, afternoon and evening for the chosen professional, a time zone note, and a summary that springs up from the bottom with the time rolling in on every pick.
- [Swipe to confirm](https://goodui.dev/native/components/swipe-to-confirm.md): Slide to confirm: the thumb follows the finger 1:1, the track fills behind it and the label fades, a tick marks the point of no return, and at the end the track gathers into a spinner and opens into the result.
- [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.
- [Text field](https://goodui.dev/native/components/text-field.md): A text field whose label glides up as you focus it, with helper and error text that slide in, a shake and haptic on error, clear and reveal buttons, a character counter and a multiline mode that grows with its text.
- [Checkbox and radio](https://goodui.dev/native/components/checkbox.md): Checkboxes whose check draws itself in (an indeterminate dash retracts into it) and radios whose dot pops into the center, inline or as list rows, with CheckboxGroup and RadioGroup helpers.
- [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.

## Guidance for AI tools

Booking confirm screen: The last step of a booking flow: a summary card, client details, notes and the cancellation policy, booked with a slide (or a button). The slider spins while the request runs, then the screen gives way to a success check with confetti, Add to calendar and Done. 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
