Saltar al contenido principal

<ReservationSummary>

Post-reservation breakdown. Reads useReservation().data, groups the server-confirmed holds by ticket-type ID (preserving wave-level splits), resolves human-readable names from useAvailability(), and renders via the same <BreakdownTree> primitive <EstimateBreakdown> uses — so the visual contract is identical pre- and post-reservation.

Import

import { ReservationSummary } from "@feelrift/react";

Basic usage

import { ReservationSummary, RiftEvent, RiftProvider } from "@feelrift/react";

<RiftProvider>
<RiftEvent eventId="evt_summerfest_2026">
<ReservationSummary />
</RiftEvent>
</RiftProvider>;

Props

Accepts all HTMLAttributes<HTMLDivElement> plus:

NameTypeRequiredDefaultDescription
asChildbooleanNofalseSwap the root element via Radix Slot.
childrenReactNodeNoReplace the default rendering. Composed inside the SDK's wrapper.
emptyFallbackReactNodeNonullRendered when there is no active reservation.
disclaimerReactNode | nullNoLocale string estimate.disclaimerOverride the disclaimer rendered near the total. Pass null to hide entirely.
classNamestringNoAppended to the SDK's rift-reservation-summary class.
…restHTMLAttributes<HTMLDivElement>NoForwarded to the root element.

emptyFallback

Rendered when useReservation().data === null — typically the pre-reserve state or after clearReservation() runs. Pass a placeholder string or skeleton when the surrounding layout needs content; leave as the default null when the component should simply vanish until a reservation exists.

disclaimer

Same default as <EstimateBreakdown>:

"We pick the cheapest available tier first. Final price (including any fees) is confirmed when you reserve."

Visible post-reservation too because checkout may add modifier steps (platform fees, taxes) the reservation breakdown doesn't include. Override per-instance, globally via <RiftProvider strings={{ "estimate.disclaimer": "…" }}>, or hide with disclaimer={null}.

Render output

Default rendering uses <BreakdownTree> — same shape as <EstimateBreakdown>:

General admission
1× Early bird $80.00
1× Regular $100.00
Subtotal $180.00
VIP
2× Standard $400.00
─────────────────────────────────
Total $580.00

We pick the cheapest available tier first. Final price
(including any fees) is confirmed when you reserve.

When a ticket type spans exactly one wave, the subtotal row is omitted (one line already shows the total for that type). When it spans multiple waves, both the per-line price and the subtotal appear so the math is legible.

Prices format via useLocale().formatCurrency against the reservation's currency.

Behavior

  • Data source. Reads useReservation().reservation (server-confirmed holds with waveId carried per hold), useReservation().breakdown (the server's modifier-inclusive pricing engine output), and useAvailability().data (cached availability tree for name lookup).
  • Total vs subtotal. When the breakdown is present, the component renders the modifier steps (fees, taxes) and the modifier-inclusive Total. When the breakdown is missing (e.g. rehydrated from an older session before the breakdown was persisted), it falls back to the line-items-only subtotal plus the disclaimer.
  • Name resolution. Wave and ticket-type names come from the cached availability tree. If availability hasn't loaded yet, falls back to IDs — better than rendering nothing.
  • No fetch trigger. Mounting doesn't issue any requests; the reservation is created by <ReserveButton> or useReservation().createReservation().
  • Source of truth. Line items shown come from the reservation response. The estimate the UI captured at reservation time is NOT shown here — its purpose is reconciliation, surfaced by <PriceChangedWarning>.
  • Persisted across reloads. The reservation is part of the SDK's persistent state; this component paints the same data after a refresh as long as the reservation hasn't expired.

Examples

Default rendering

<ReservationSummary />

Renders the tree as soon as a reservation exists. Names resolved automatically.

With an empty-state placeholder

<ReservationSummary emptyFallback={<p>Reserve to see the breakdown.</p>} />

Custom rendering

import { ReservationSummary, useLocale, useReservation } from "@feelrift/react";

function CompactSummary() {
const reservation = useReservation().data;
const { formatCurrency } = useLocale();
if (!reservation) return null;

const totalCount = reservation.holds.reduce((s, h) => s + h.quantity, 0);
return (
<ReservationSummary>
<p>
{totalCount} ticket{totalCount === 1 ? "" : "s"}:{" "}
<strong>{formatCurrency(reservation.subtotal)}</strong>
</p>
</ReservationSummary>
);
}

Hide the disclaimer (you display equivalent copy elsewhere)

<ReservationSummary disclaimer={null} />
  • <EstimateBreakdown> — the pre-reservation counterpart, same render primitive.
  • useReservation — underlying data source. Public types exported from @feelrift/react.
  • <PriceChangedWarning> — surfaces estimate-vs-actual deltas.
  • <Countdown> — usually rendered alongside.
  • Pricing and estimates — the wave-tier model, the disclaimer's purpose post-reservation.