Fliin
On this page

Screens / commerce

Stay booking

Books a stay in a holiday rental: check-in and check-out around nights already taken, adults and children, an optional arrival time, and the price details that follow the choice.

16 of 16 variants pass
Stay booking, dates state
Platform
Brightness
Text scale
Direction

Import

Stay booking is part of Fliin Pro. With a license key, sign in once with fliin login, then add it in a Flutter app where fliin init has run:

fliin login
fliin add booking

Also installs: alert, app-bar, button, calendar, core, date-field, date-picker, empty-state, icons, list-row, number-field, order-summary, page, radio, range-calendar, result-card, section-header, sheet, skeleton, surface, text, time-field

Examples

Dates

Ready for dates: the calendar shows the nights already taken, and the price waits for a stay. now fixes the clock, here to the sample's October 20, 2026.

Stay booking, dates state
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingDatesExample extends StatelessWidget {
  const BookingDatesExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Priced

A stay chosen: the price follows the dates and the guests, night by night, before the user books.

Stay booking, priced state
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingPricedExample extends StatelessWidget {
  const BookingPricedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(stay: sampleBookingStay),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Sending

Booking sent: the button waits for the service and the form stays readable.

Stay booking, sending state
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingSendingExample extends StatelessWidget {
  const BookingSendingExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(stay: sampleBookingStay, sending: true),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Unconfirmed

The service did not answer in time: the notice says the booking may not have gone through and offers to check.

Stay booking, unconfirmed state
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingUnconfirmedExample extends StatelessWidget {
  const BookingUnconfirmedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(stay: sampleBookingStay, notice: BookingNotice.unconfirmed),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Taken

A night of the stay was taken at booking time: the notice asks for other dates, and the calendar shows it taken.

Stay booking, taken state
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingTakenExample extends StatelessWidget {
  const BookingTakenExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(
        booked: {...sampleBookingTaken, DateTime(2026, 10, 25)},
        latency: const Duration(milliseconds: 600),
      ),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(stay: sampleBookingStay, notice: BookingNotice.datesTaken),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Loading

While the property and its calendar load, placeholders keep the layout.

Stay booking, loading state
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingLoadingExample extends StatelessWidget {
  const BookingLoadingExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: const BookingLoading(),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Error

When loading fails, the screen says so and offers to try again.

Stay booking, error state
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingErrorExample extends StatelessWidget {
  const BookingErrorExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: const BookingFailed(),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Offline

Without a connection, the screen asks to reconnect rather than showing an error.

Stay booking, offline state
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingOfflineExample extends StatelessWidget {
  const BookingOfflineExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: const BookingOffline(),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Policy

Self check-in with its conditions: showArrivalTime: false leaves out the arrival time, footer puts the cancellation policy and the house rules under the price.

Stay booking, policy state
import 'package:your_app/ui/fliin/components/list_row/fl_list_row.dart';
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/icons/fl_icons.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingPolicyExample extends StatelessWidget {
  const BookingPolicyExample({super.key});

  @override
  Widget build(BuildContext context) {
    return BookingScreen.standalone(
      service: SampleBookingService(latency: const Duration(milliseconds: 600)),
      propertyId: sampleBookingProperty.id,
      now: () => DateTime(2026, 10, 20),
      initial: sampleBookingReady(stay: sampleBookingStay),
      showArrivalTime: false,
      footer: FlListGroup(
        children: [
          FlListRow(
            leading: FlIcon(FlIcons.calendar),
            title: 'Free cancellation until October 21',
            subtitle: 'Then the first night is kept',
          ),
          FlListRow(
            leading: FlIcon(FlIcons.circleInfo),
            title: 'House rules',
            trailing: const FlListRowChevron(),
            onPressed: () {},
          ),
        ],
      ),
      onBooked: (_) {},
      onBack: () {},
    );
  }
}

Routing

fliin add booking prints the route for the router it finds in your pubspec, a file next to the page that wires its navigation. Each of them:

go_router

// lib/booking_route.dart, next to booking_page.dart.
import 'package:go_router/go_router.dart';

import 'booking_page.dart';

/// Add bookingRoute to the routes of your GoRouter.
final bookingRoute = GoRoute(
  path: '/book',
  builder: (context, state) => BookingPage(
    // The path of the booking confirmation of your app.
    onBooked: (booking) => context.pushReplacement('/bookings/${Uri.encodeComponent(booking.reference)}'),
    // Alone in the stack (deep link, go): your app's home.
    onBack: () => context.canPop() ? context.pop() : context.go('/'),
  ),
);

navigator

// lib/booking_route.dart, next to booking_page.dart.
import 'package:flutter/material.dart';

import 'booking_page.dart';

/// Opens “Stay booking”: `Navigator.of(context).push(bookingRoute(confirmationPage: …))`.
/// [confirmationPage] builds the booking confirmation of your app.
Route<void> bookingRoute({
  required Widget Function(String reference) confirmationPage,
}) => MaterialPageRoute<void>(
  builder: (context) => BookingPage(
    onBooked: (booking) => Navigator.of(context).pushReplacement(MaterialPageRoute<void>(builder: (_) => confirmationPage(booking.reference))),
    onBack: () => Navigator.of(context).maybePop(),
  ),
);

State

The controller is a ChangeNotifier from widgets.dart, with no package. fliin add booking prints the page that holds it with the state management it finds, its imports written for your package; below they read your_app. Your backend implements the Service interface of the screen's _data.dart file:

none

// lib/booking_page.dart
// Your backend: implement BookingService (booking_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';

class BookingPage extends StatelessWidget {
  const BookingPage({
    super.key,
    required this.onBooked,
    required this.onBack,
  });

  final ValueChanged<BookingConfirmation> onBooked;
  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => BookingScreen.standalone(
    service: SampleBookingService(),
    propertyId: 'collioure-port',
    onBooked: onBooked,
    onBack: onBack,
  );
}

provider

// lib/booking_page.dart
// Your backend: implement BookingService (booking_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

class BookingPage extends StatelessWidget {
  const BookingPage({
    super.key,
    required this.onBooked,
    required this.onBack,
  });

  final ValueChanged<BookingConfirmation> onBooked;
  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
    create: (_) => BookingController(service: SampleBookingService(), propertyId: 'collioure-port')..load(),
    child: Builder(
      builder: (context) => BookingScreen(
        controller: context.read<BookingController>(),
        onBooked: onBooked,
        onBack: onBack,
      ),
    ),
  );
}

riverpod

// lib/booking_page.dart
// Your backend: implement BookingService (booking_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final bookingControllerProvider = Provider.autoDispose<BookingController>((ref) {
  final controller = BookingController(service: SampleBookingService(), propertyId: 'collioure-port')..load();
  ref.onDispose(controller.dispose);
  return controller;
});

class BookingPage extends ConsumerWidget {
  const BookingPage({
    super.key,
    required this.onBooked,
    required this.onBack,
  });

  final ValueChanged<BookingConfirmation> onBooked;
  final VoidCallback onBack;

  @override
  Widget build(BuildContext context, WidgetRef ref) => BookingScreen(
    controller: ref.watch(bookingControllerProvider),
    onBooked: onBooked,
    onBack: onBack,
  );
}

bloc

// lib/booking_page.dart
// Your backend: implement BookingService (booking_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/booking/booking_controller.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_data.dart';
import 'package:your_app/ui/fliin/screens/booking/booking_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

/// The screen's controller as a bloc, for your BlocListener and BlocBuilder:
/// one emission per controller notification. `version` tells them apart
/// when `state` does not change (mode, filters, text…, read them on
/// `controller`). The screen listens to the controller itself.
class BookingCubit extends Cubit<({BookingState state, int version})> {
  BookingCubit(this.controller) : super((state: controller.state, version: 0)) {
    controller.addListener(_changed);
  }

  final BookingController controller;

  void _changed() => emit((state: controller.state, version: state.version + 1));

  @override
  Future<void> close() {
    controller
      ..removeListener(_changed)
      ..dispose();
    return super.close();
  }
}

class BookingPage extends StatelessWidget {
  const BookingPage({
    super.key,
    required this.onBooked,
    required this.onBack,
  });

  final ValueChanged<BookingConfirmation> onBooked;
  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => BlocProvider(
    create: (_) => BookingCubit(BookingController(service: SampleBookingService(), propertyId: 'collioure-port')..load()),
    child: Builder(
      builder: (context) => BookingScreen(
        controller: context.read<BookingCubit>().controller,
        onBooked: onBooked,
        onBack: onBack,
      ),
    ),
  );
}

API

BookingScreen: class extends StatefulWidget
BookingScreen.new: const new({super.key, required BookingController controller, required ValueChanged<BookingConfirmation> onBooked, VoidCallback? onBack, bool showArrivalTime, Widget? footer})
BookingScreen.standalone: const new({super.key, required BookingService service, required String propertyId, required ValueChanged<BookingConfirmation> onBooked, DateTime Function()? now, BookingState? initial, VoidCallback? onBack, bool showArrivalTime, Widget? footer})
BookingScreen.controller: get BookingController?
BookingScreen.service: get BookingService?
BookingScreen.propertyId: get String?
BookingScreen.now: get DateTime Function()?
BookingScreen.initial: get BookingState?
BookingScreen.onBooked: get ValueChanged<BookingConfirmation>
BookingScreen.onBack: get VoidCallback?
BookingScreen.showArrivalTime: get bool
BookingScreen.footer: get Widget?
BookingScreen.createState: State<BookingScreen>()
BookingAvailability: final class
BookingAvailability.new: const new({Map<DateTime, Set<DateTime>> taken, Map<DateTime, bool> failed})
BookingAvailability.taken: get Map<DateTime, Set<DateTime>>
BookingAvailability.failed: get Map<DateTime, bool>
BookingAvailability.knows: bool(DateTime month)
BookingAvailability.isUnavailable: bool(DateTime day)
BookingAvailability.problem: get BookingStayCheck?
BookingAvailability.check: BookingStayCheck(FlDateRange stay)
BookingStayCheck: enum {free, checking, failed, offline, taken}
BookingStayCheck.free: static final BookingStayCheck
BookingStayCheck.checking: static final BookingStayCheck
BookingStayCheck.failed: static final BookingStayCheck
BookingStayCheck.offline: static final BookingStayCheck
BookingStayCheck.taken: static final BookingStayCheck
BookingPrice: sealed class permits {BookingPriceFailed, BookingPriceNone, BookingPricePending, BookingPriceShown}
BookingPrice.new: const new()
BookingPriceNone: final class extends BookingPrice
BookingPriceNone.new: const new()
BookingPricePending: final class extends BookingPrice
BookingPricePending.new: const new()
BookingPriceShown: final class extends BookingPrice
BookingPriceShown.new: const new(BookingQuote quote)
BookingPriceShown.quote: get BookingQuote
BookingPriceFailed: final class extends BookingPrice
BookingPriceFailed.new: const new({required bool offline})
BookingPriceFailed.offline: get bool
BookingBlocker: enum {noDates, noNights, datesTaken, pastArrival, checking, pricing, failed, offline, sending, unconfirmed}
BookingBlocker.noDates: static final BookingBlocker
BookingBlocker.noNights: static final BookingBlocker
BookingBlocker.datesTaken: static final BookingBlocker
BookingBlocker.pastArrival: static final BookingBlocker
BookingBlocker.checking: static final BookingBlocker
BookingBlocker.pricing: static final BookingBlocker
BookingBlocker.failed: static final BookingBlocker
BookingBlocker.offline: static final BookingBlocker
BookingBlocker.sending: static final BookingBlocker
BookingBlocker.unconfirmed: static final BookingBlocker
BookingNotice: enum {declined, unconfirmed, notBooked, datesTaken}
BookingNotice.declined: static final BookingNotice
BookingNotice.unconfirmed: static final BookingNotice
BookingNotice.notBooked: static final BookingNotice
BookingNotice.datesTaken: static final BookingNotice
BookingState: sealed class permits {BookingBooked, BookingFailed, BookingLoading, BookingOffline, BookingReady}
BookingState.new: const new()
BookingLoading: final class extends BookingState
BookingLoading.new: const new()
BookingFailed: final class extends BookingState
BookingFailed.new: const new()
BookingOffline: final class extends BookingState
BookingOffline.new: const new()
BookingReady: final class extends BookingState
BookingReady.new: const new({required BookingProperty property, BookingAvailability availability, FlDateRange? stay, BookingGuests guests, FlTime? arrivalTime, BookingPrice price, bool sending, BookingNotice? notice, BookingRequest? unconfirmed, FlDateRange? refused})
BookingReady.property: get BookingProperty
BookingReady.availability: get BookingAvailability
BookingReady.stay: get FlDateRange?
BookingReady.guests: get BookingGuests
BookingReady.arrivalTime: get FlTime?
BookingReady.price: get BookingPrice
BookingReady.sending: get bool
BookingReady.notice: get BookingNotice?
BookingReady.unconfirmed: get BookingRequest?
BookingReady.refused: get FlDateRange?
BookingReady.maxAdults: get int
BookingReady.maxChildren: get int
BookingReady.nights: get int
BookingReady.check: get BookingStayCheck
BookingReady.blockerOn: BookingBlocker?(DateTime today)
BookingReady.copyWith: BookingReady({BookingAvailability? availability, FlDateRange? stay, bool clearStay, BookingGuests? guests, FlTime? arrivalTime, bool clearArrivalTime, BookingPrice? price, bool? sending, BookingNotice? notice, bool clearNotice, BookingRequest? unconfirmed, bool clearUnconfirmed, FlDateRange? refused, bool clearRefused})
BookingBooked: final class extends BookingState
BookingBooked.new: const new(BookingConfirmation confirmation)
BookingBooked.confirmation: get BookingConfirmation
BookingController: class extends ChangeNotifier
BookingController.new: new({required BookingService service, required String propertyId, DateTime Function()? now, BookingState initial})
BookingController.service: get BookingService
BookingController.propertyId: get String
BookingController.now: get DateTime Function()
BookingController.state: get BookingState
BookingController.firstDay: get DateTime
BookingController.blocker: get BookingBlocker?
BookingController.lastDay: get DateTime?
BookingController.load: Future<bool>()
BookingController.showMonth: void(DateTime month)
BookingController.setStay: bool(FlDateRange? stay)
BookingController.setAdults: bool(int adults)
BookingController.setChildren: bool(int children)
BookingController.setArrivalTime: bool(FlTime? time)
BookingController.retry: bool()
BookingController.book: Future<bool>()
BookingController.checkBooking: Future<bool>()
BookingController.dispose: void()
bookingNights: int(FlDateRange stay)
bookingNightsOf: List<DateTime>(FlDateRange stay)
bookingMonthOf: DateTime(DateTime day)
BookingProperty: final class
BookingProperty.new: const new({required String id, required String title, required String location, required String nightlyPrice, required int maxGuests, required int maxAdults, required int maxChildren, double? rating, int? reviews, ImageProvider? image, String? checkInHours, List<FlTime> arrivalTimes, int bookableMonths})
BookingProperty.id: get String
BookingProperty.title: get String
BookingProperty.location: get String
BookingProperty.nightlyPrice: get String
BookingProperty.maxGuests: get int
BookingProperty.maxAdults: get int
BookingProperty.maxChildren: get int
BookingProperty.rating: get double?
BookingProperty.reviews: get int?
BookingProperty.image: get ImageProvider?
BookingProperty.checkInHours: get String?
BookingProperty.arrivalTimes: get List<FlTime>
BookingProperty.bookableMonths: get int
BookingGuests: final class
BookingGuests.new: const new({required int adults, int children})
BookingGuests.adults: get int
BookingGuests.children: get int
BookingGuests.total: get int
BookingGuests.operator ==: bool(Object other)
BookingGuests.hashCode: get int
BookingGuests.toString: String()
BookingFeeKind: enum {cleaning, service, tourismTax}
BookingFeeKind.cleaning: static final BookingFeeKind
BookingFeeKind.service: static final BookingFeeKind
BookingFeeKind.tourismTax: static final BookingFeeKind
BookingFee: final class
BookingFee.new: const new(BookingFeeKind kind, String amount)
BookingFee.kind: get BookingFeeKind
BookingFee.amount: get String
BookingQuote: final class
BookingQuote.new: const new({required String key, required int nights, required String nightlyPrice, required String stayPrice, required List<BookingFee> fees, required String total})
BookingQuote.key: get String
BookingQuote.nights: get int
BookingQuote.nightlyPrice: get String
BookingQuote.stayPrice: get String
BookingQuote.fees: get List<BookingFee>
BookingQuote.total: get String
BookingRequest: final class
BookingRequest.new: const new({required String propertyId, required FlDateRange stay, required BookingGuests guests, required String quoteKey, FlTime? arrivalTime})
BookingRequest.propertyId: get String
BookingRequest.stay: get FlDateRange
BookingRequest.guests: get BookingGuests
BookingRequest.quoteKey: get String
BookingRequest.arrivalTime: get FlTime?
BookingConfirmation: final class
BookingConfirmation.new: const new({required String reference, required FlDateRange stay, required String total})
BookingConfirmation.reference: get String
BookingConfirmation.stay: get FlDateRange
BookingConfirmation.total: get String
BookingNoNetwork: final class implements Exception
BookingNoNetwork.new: const new()
BookingDatesTaken: final class implements Exception
BookingDatesTaken.new: const new()
BookingDeclined: final class implements Exception
BookingDeclined.new: const new()
BookingOutcome: sealed class permits {BookingOutcomeBooked, BookingOutcomeNotBooked, BookingOutcomeStillPending}
BookingOutcome.new: const new()
BookingOutcomeBooked: final class extends BookingOutcome
BookingOutcomeBooked.new: const new(BookingConfirmation confirmation)
BookingOutcomeBooked.confirmation: get BookingConfirmation
BookingOutcomeNotBooked: final class extends BookingOutcome
BookingOutcomeNotBooked.new: const new()
BookingOutcomeStillPending: final class extends BookingOutcome
BookingOutcomeStillPending.new: const new()
BookingService: abstract interface class
BookingService.new: new()
BookingService.load: abstract Future<BookingProperty>(String propertyId)
BookingService.unavailableNights: abstract Future<Set<DateTime>>(String propertyId, DateTime month)
BookingService.quote: abstract Future<BookingQuote>(String propertyId, FlDateRange stay, BookingGuests guests)
BookingService.book: abstract Future<BookingConfirmation>(BookingRequest request)
BookingService.unconfirmed: abstract Future<BookingRequest?>(String propertyId)
BookingService.outcome: abstract Future<BookingOutcome>(String quoteKey)
sampleBookingProperty: const dynamic
sampleBookingQuote: BookingQuote(String propertyId, FlDateRange stay, BookingGuests guests)
SampleBookingService: final class implements BookingService
SampleBookingService.new: new({Set<DateTime>? booked, Set<DateTime> takenAtBooking, Duration latency})
SampleBookingService.latency: get Duration
SampleBookingService.takenAtBooking: get Set<DateTime>
SampleBookingService.load: Future<BookingProperty>(String propertyId)
SampleBookingService.unavailableNights: Future<Set<DateTime>>(String propertyId, DateTime month)
SampleBookingService.quote: Future<BookingQuote>(String propertyId, FlDateRange stay, BookingGuests guests)
SampleBookingService.unconfirmed: Future<BookingRequest?>(String propertyId)
SampleBookingService.outcome: Future<BookingOutcome>(String quoteKey)
SampleBookingService.book: Future<BookingConfirmation>(BookingRequest request)
sampleBookingTaken: get dynamic
sampleBookingStay: get dynamic
sampleBookingReady: BookingReady({FlDateRange? stay, bool priced, bool sending, BookingNotice? notice})
bookingL10n: const Map<String, Map<String, String>>
BookingStrings: final class
BookingStrings.new: const new(String language)
BookingStrings.of: factory new(BuildContext context)
BookingStrings.language: get String
BookingStrings.count: String(int n)
BookingStrings.title: get String
BookingStrings.back: get String
BookingStrings.loading: get String
BookingStrings.nightly: String(String price)
BookingStrings.perNight: get String
BookingStrings.rating: String(double rating, int count)
BookingStrings.dates: get String
BookingStrings.closeCalendar: get String
BookingStrings.nights: String(int count)
BookingStrings.noNights: get String
BookingStrings.pastArrival: get String
BookingStrings.datesTaken: get String
BookingStrings.adults: get String
BookingStrings.arrival: get String
BookingStrings.departure: get String
BookingStrings.chooseDates: get String
BookingStrings.stayDates: String(DateTime start, DateTime end, int nights)
BookingStrings.shortDate: String(DateTime day)
BookingStrings.noArrivalTime: get String
BookingStrings.close: get String
BookingStrings.adultsHelp: String(int maxGuests)
BookingStrings.guests: get String
BookingStrings.hour: String(FlTime time)
BookingStrings.fewerAdults: get String
BookingStrings.moreAdults: get String
BookingStrings.children: get String
BookingStrings.childrenHelp: get String
BookingStrings.fewerChildren: get String
BookingStrings.moreChildren: get String
BookingStrings.arrivalTime: get String
BookingStrings.summary: get String
BookingStrings.stayLine: String(int nights, String price)
BookingStrings.cleaning: get String
BookingStrings.service: get String
BookingStrings.tourismTax: get String
BookingStrings.total: get String
BookingStrings.updating: get String
BookingStrings.newTotal: String(String total)
BookingStrings.book: String(String total)
BookingStrings.needDates: get String
BookingStrings.needNights: get String
BookingStrings.needOtherDates: get String
BookingStrings.checking: get String
BookingStrings.pricing: get String
BookingStrings.cantBook: get String
BookingStrings.cantBookOffline: get String
BookingStrings.checkFailed: get String
BookingStrings.checkOffline: get String
BookingStrings.retry: get String
BookingStrings.declinedNotice: get String
BookingStrings.unconfirmedNotice: get String
BookingStrings.notBookedNotice: get String
BookingStrings.checkBooking: get String
BookingStrings.takenNotice: get String
BookingStrings.booked: get String
BookingStrings.errorTitle: get String
BookingStrings.errorMessage: get String
BookingStrings.offlineTitle: get String
BookingStrings.offlineMessage: get String

Strings

Every label in English, French and Arabic. The screen follows the closest Localizations; the same table is in the manifest, ready for your ARB files.

Keyenfrar
bookingTitleBookingRéservationالحجز
bookingBackBackRetourرجوع
bookingLoadingLoading the placeChargement du logementجارٍ تحميل المسكن
bookingNightly{price} per night{price} la nuit{price} لليلة
bookingPerNightper nightla nuitلليلة
bookingRating{rating} · {count} reviews{rating} · {count} avis{rating} · التقييمات: {count}
bookingRatingOne{rating} · 1 review{rating} · 1 avis{rating} · تقييم واحد
bookingDecimal.,٫
bookingDatesDates of stayDates du séjourتواريخ الإقامة
bookingCloseCalendarClose the calendarFermer le calendrierإغلاق التقويم
bookingNightsOne1 night1 nuitليلة واحدة
bookingNightsMany{count} nights{count} nuitsعدد الليالي: {count}
bookingNoNightsDeparture comes after arrival: choose at least one night.Le départ suit l’arrivée : choisissez au moins une nuit.المغادرة بعد الوصول: اختر ليلة واحدة على الأقل.
bookingDatesTakenThese dates are no longer free. Choose others.Ces dates ne sont plus libres. Choisissez-en d’autres.هذه التواريخ لم تعد متاحة. اختر غيرها.
bookingPastArrivalThe arrival day has passed. Choose other dates.Le jour d’arrivée est passé. Choisissez d’autres dates.يوم الوصول قد مضى. اختر تواريخ أخرى.
bookingAdultsAdultsAdultesالبالغون
bookingArrivalCheck-inArrivéeالوصول
bookingDepartureCheck-outDépartالمغادرة
bookingChooseDatesChoose your datesChoisir les datesاختر التواريخ
bookingStayDates{start} – {end} · {nights}{start} – {end} · {nights}{start} – {end} · {nights}
bookingShortDate{weekday}, {month} {day}{weekday} {day} {month}{weekday} {day} {month}
bookingWeekdaysShortMon,Tue,Wed,Thu,Fri,Sat,Sunlun.,mar.,mer.,jeu.,ven.,sam.,dim.الاثنين,الثلاثاء,الأربعاء,الخميس,الجمعة,السبت,الأحد
bookingMonthsShortJan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Decjanv.,févr.,mars,avr.,mai,juin,juil.,août,sept.,oct.,nov.,déc.يناير,فبراير,مارس,أبريل,مايو,يونيو,يوليو,أغسطس,سبتمبر,أكتوبر,نوفمبر,ديسمبر
bookingNoArrivalTimeNot setNon préciséeغير محدد
bookingCloseCloseFermerإغلاق
bookingGuestsGuestsVoyageursالضيوف
bookingAdultsHelpAges 13 and over · up to {count} guests in all13 ans et plus · {count} voyageurs au plus en tout١٣ سنة فأكثر · الحد الأقصى للضيوف: {count}
bookingFewerAdultsFewer adultsMoins d’adultesتقليل البالغين
bookingMoreAdultsMore adultsPlus d’adultesزيادة البالغين
bookingChildrenChildrenEnfantsالأطفال
bookingChildrenHelpAges 2 to 12De 2 à 12 ansمن ٢ إلى ١٢ سنة
bookingFewerChildrenFewer childrenMoins d’enfantsتقليل الأطفال
bookingMoreChildrenMore childrenPlus d’enfantsزيادة الأطفال
bookingArrivalTimeArrival time (optional)Heure d’arrivée (facultatif)وقت الوصول (اختياري)
bookingHour{h12} {period}{h} h{h}:{mm}
bookingHourMinutes{h12}:{mm} {period}{h} h {mm}{h}:{mm}
bookingAmAMAMص
bookingPmPMPMم
bookingSummaryPrice detailsDétail du prixتفاصيل السعر
bookingStayLine{nights} × {price}{nights} × {price}{nights} × {price}
bookingCleaningCleaning feeFrais de ménageرسوم التنظيف
bookingServiceService feeFrais de serviceرسوم الخدمة
bookingTourismTaxTourist taxTaxe de séjourضريبة الإقامة
bookingTotalTotalTotalالإجمالي
bookingUpdatingWorking out the priceCalcul du prixجارٍ حساب السعر
bookingNewTotalNew total: {total}Nouveau total : {total}الإجمالي الجديد: {total}
bookingBookBook · {total}Réserver · {total}احجز · {total}
bookingNeedDatesChoose your dates to bookChoisissez vos dates pour réserverاختر تواريخك للحجز
bookingNeedNightsChoose at least one nightChoisissez au moins une nuitاختر ليلة واحدة على الأقل
bookingNeedOtherDatesChoose other datesChoisissez d’autres datesاختر تواريخ أخرى
bookingCheckingChecking availability…Vérification des disponibilités…جارٍ التحقق من التوفر…
bookingPricingWorking out the price…Calcul du prix…جارٍ حساب السعر…
bookingCantBookBooking unavailable for nowRéservation impossible pour l’instantالحجز غير متاح حاليًا
bookingCantBookOfflineBooking needs a connectionRéservation impossible hors ligneالحجز غير ممكن دون اتصال
bookingCheckFailedThe price or the availability couldn’t load.Le prix ou les disponibilités n’ont pas pu se charger.تعذّر تحميل السعر أو التوفر.
bookingCheckOfflineYou’re offline: booking needs a connection to check the dates and the price.Vous êtes hors ligne : la réservation demande une connexion pour vérifier les dates et le prix.أنت غير متصل: يتطلب الحجز اتصالًا للتحقق من التواريخ والسعر.
bookingRetryTry againRéessayerأعد المحاولة
bookingDeclinedNoticeThe booking was refused. Nothing is booked: try again or change your choices.La réservation a été refusée. Rien n’est réservé : réessayez ou changez vos choix.تم رفض الحجز. لم يُحجز شيء: أعد المحاولة أو غيّر اختياراتك.
bookingUnconfirmedNoticeWe couldn’t confirm the booking. It may have gone through: check it before changing anything.La réservation n’a pas pu être confirmée. Elle a peut-être été faite : vérifiez-la avant de changer quoi que ce soit.تعذّر تأكيد الحجز، وربما تمّ. تحقّق منه قبل أي تغيير.
bookingNotBookedNoticeNo booking was made. You can book again.Aucune réservation n’a été faite. Vous pouvez réserver.لم يتم أي حجز. يمكنك الحجز من جديد.
bookingCheckBookingCheck the bookingVérifier la réservationالتحقق من الحجز
bookingTakenNoticeThese dates can no longer be booked. They’re kept above: choose others.Ces dates ne peuvent plus être réservées. Elles sont gardées plus haut : choisissez-en d’autres.لم يعد بالإمكان حجز هذه التواريخ. ما زالت محفوظة أعلاه: اختر غيرها.
bookingBookedBooking confirmedRéservation confirméeتم تأكيد الحجز
bookingErrorTitleThis place couldn’t loadImpossible de charger le logementتعذّر تحميل المسكن
bookingErrorMessageTry again in a moment.Réessayez dans un instant.أعد المحاولة بعد قليل.
bookingOfflineTitleYou’re offlineVous êtes hors ligneأنت غير متصل
bookingOfflineMessageBooking needs a connection to check the dates and the price.La réservation demande une connexion pour vérifier les dates et le prix.يتطلب الحجز اتصالًا للتحقق من التواريخ والسعر.

Reference renders

The 16 images published with version 0.3.5, rendered by the shared harness on macOS with Flutter 3.47.7. Each shows every state side by side, at the size of an iPhone (390 × 844) or of an Android phone (412 × 915). fliin verify booking compares your copy to them.

iOS · Light
Stay booking, iOS, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Stay booking, iOS, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Stay booking, iOS, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Stay booking, iOS, Light, text 2.0×, Right to left
Text 2.0× · Right to left
iOS · Dark
Stay booking, iOS, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Stay booking, iOS, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Stay booking, iOS, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Stay booking, iOS, Dark, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Light
Stay booking, Android, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Stay booking, Android, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Stay booking, Android, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Stay booking, Android, Light, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Dark
Stay booking, Android, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Stay booking, Android, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Stay booking, Android, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Stay booking, Android, Dark, text 2.0×, Right to left
Text 2.0× · Right to left

Use it to

  • offer the reservation of a holiday rental with its price
  • pick a stay that never crosses a night already let
  • show the price of a stay that follows the nights and the guests
  • explain that a night was just let to someone else
  • keep the guests of a stay within what the rental sleeps
  • pick an arrival time among the slots the host offers
Not for
  • paying for a cart: use the checkout screen (checkout)
  • a period in a form without prices or availability: use the date range picker (date-range-picker)
States
  • Dates
  • Priced
  • Sending
  • Unconfirmed
  • Taken
  • Loading
  • Error
  • Offline

Arrows to move, Enter to open, Escape to close.