import { useState } from 'react'; import { Offer, Order } from '@duffel/api'; import { Card } from '../components/Card'; import { formatCurrency, getAirlineLogoUrl } from '../utils'; import { GENERIC_ERROR_MESSAGE } from './constants'; interface BookingCardProps { offer: Offer; onSuccess(order: Order): void; onError(e: Error): void; } export const BookingCard: React.FC = ({ offer, onSuccess, onError, }) => { const [isFetching, setIsFetching] = useState(false); const bookOffer = async () => { setIsFetching(true); const res = await fetch(`/api/book`, { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ offerId: offer.id, passengers: [ { id: offer.passengers[0].id, born_on: '1987-07-24', family_name: 'Earheart', given_name: 'Amelia', gender: 'f', title: 'ms', email: 'amelia@duffel.com', phone_number: '+442080160509', }, ], currency: offer.total_currency, amount: offer.total_amount, }), }); const { order, errors } = await res.json(); setIsFetching(false); if (Array.isArray(errors)) { onError(new Error(errors[0].title)); return; } if (!order) { onError(new Error(GENERIC_ERROR_MESSAGE)); return; } onSuccess(order); }; return ( <>

Example booking flow

2/3 We have a result, now let’s book it.

{offer.owner.name} {offer.owner.name} {formatCurrency(offer.total_amount, offer.total_currency)} await bookOffer()} > {isFetching ? 'Booking…' : 'Book'} ); };