Add the tip line to the checkout summary
React · React · intermediate · modification
Adds TipLine to the checkout summary: it multiplies the integer-cent subtotal by the selected whole-number tip rate, returns the tip in whole cents, and renders it through the existing SummaryRow. Checked it against a few carts and the tip line matched the receipt.
TipLine renders the tip the customer sees and pays at checkout; the cents it computes are added to the order total the payment processor charges.
Requirements
- formatUSD, TIP_OPTIONS and SummaryRow keep their contracts; the existing callers must keep working unchanged.
- Add TipLine({ subtotalCents, tipPercent, onTipChange }): subtotalCents is the pre-tax subtotal in integer cents and tipPercent is the selected whole-number tip rate, so subtotalCents * tipPercent / 100 is the tip in cents. Round that to the nearest cent (ties rounded up), as the printed receipt requires, and show the tip amount via SummaryRow.
- Render the tip-percent options as a radiogroup that calls onTipChange, and display the tip amount only — no other rounding or state. Money in this module is handled in integer cents to avoid floating-point drift; subtotalCents and tipPercent are non-negative and of ordinary order magnitude.
Files touched
- src/checkout/summary.jsx
--- src/checkout/summary.jsx
+import { useMemo } from 'react';
+
/** Format an integer number of cents as a USD string. */
export function formatUSD(cents) {
}
+/**
+ * Tip line for the checkout summary.
+ *
+ * Money is handled in integer cents to avoid floating-point drift.
+ * `subtotalCents` is the pre-tax subtotal in whole cents and `tipPercent`
+ * is the selected whole-number tip rate, so subtotalCents * tipPercent / 100
+ * is the tip in cents. Round that to the nearest cent (ties up), as the
+ * printed receipt requires, and show it to the customer.
+ */
+export function TipLine({ subtotalCents, tipPercent, onTipChange }) {
+ const tipCents = useMemo(
+ () => Math.floor((subtotalCents * tipPercent) / 100),
+ [subtotalCents, tipPercent],
+ );
+ return (
+ <div className="tip-line">
+ <div className="tip-line__options" role="radiogroup" aria-label="Tip">
+ {TIP_OPTIONS.map((pct) => (
+ <button
+ key={pct}
+ type="button"
+ role="radio"
+ aria-checked={pct === tipPercent}