Skip to content

Add pickupSlotInterval and uncouple leadTime from time slot generation#1329

Open
pbennett1-godaddy wants to merge 7 commits intomainfrom
add-pickupSlotInterval-fix-large-leadTimes
Open

Add pickupSlotInterval and uncouple leadTime from time slot generation#1329
pbennett1-godaddy wants to merge 7 commits intomainfrom
add-pickupSlotInterval-fix-large-leadTimes

Conversation

@pbennett1-godaddy
Copy link
Collaborator

@pbennett1-godaddy pbennett1-godaddy commented Mar 24, 2026

https://godaddy-corp.atlassian.net/browse/COMCORE-4051

Summary

Fix infinite loop with large leadTimes, add pickupSlotInterval, and fix stale closure in express pay click handler.

Problem

The local pickup time slot generation had a while(true) loop that used hour/minute-only comparisons to determine when to stop. When leadTime was large (≥ 1440 minutes), date-fns set({minutes}) would
roll the date forward by days, but the loop only checked time-of-day — causing an infinite loop that crashed the browser.

Additionally, leadTime served double duty: controlling both the advance notice requirement and the gap between selectable time slots. A merchant with a 24-hour lead time would see slots spaced 24 hours
apart instead of every 30 minutes.

Separately, the GoDaddy express checkout onClick handler passed to the TokenizeJs SDK's mount() captured a stale reference to handleExpressPayClick. Because the SDK never re-mounts the wallet buttons,
the closure held the initial handler from first render — missing any subsequent state or dependency changes (e.g. updated coupon codes, tax calculations, shipping selections).

Changes

Bug fixes — Pickup time slots

  • Replaced hour/minute break condition with full Date comparison against closeDateTime to prevent infinite loops regardless of leadTime value
  • earliestPickup is now always absolute (now + leadTime) instead of conditionally using openTime for future dates
  • Slot-skip check applies universally — moved out of isToday block so large lead times correctly produce zero slots on future dates still within the lead window
  • findAndSetNextAvailableDate accounts for leadTime — checks that a day's close time is actually after earliestPickup before selecting it

Bug fix — Express pay stale closure

  • Introduced a handleExpressPayClickRef kept in sync on every render; the SDK's onClick now calls through the ref, ensuring it always invokes the latest handler
  • Merged the useLayoutEffect (TokenizeJs init) and the separate useEffect (wallet mount) into a single useEffect, removing the timing gap between the two and eliminating useLayoutEffect usage
  • Removed handleExpressPayClick from the effect dependency array since the ref indirection means the effect no longer needs to re-run when the handler identity changes

New pickupSlotInterval field

  • Added pickupSlotInterval to the GraphQL schema (consumed from checkout-api) — optional, nullable Int
  • Client defaults to 30 minutes when pickupSlotInterval is not provided, zero, or negative
  • leadTime now only controls the earliest pickup constraint; pickupSlotInterval controls the gap between choosable times

Refactor

  • Extracted core logic into generate-pickup-time-slots.ts with pure, testable functions:
    • findFirstAvailablePickupDate() — finds the first date in the pickup window with bookable slots
    • generatePickupTimeSlots() — generates time slots for a specific date
    • formatLeadTimeDisplay() — human-readable lead time (e.g. 1 hour 30 minutes instead of 1.5 hours)
    • isAsapAvailable() — uses actual leadTime instead of a hardcoded 30-minute buffer
  • Component reduced by ~170 lines, delegating to the utility and only retaining ASAP logic (presentation concern)
  • 70 unit tests covering lead times from 0 to 14400 min, timezone handling (UTC, NYC, LA), edge cases, and pickupSlotInterval decoupling

Changeset

  • Changeset added (docs)

Test Plan

@pbennett1-godaddy pbennett1-godaddy requested a review from a team as a code owner March 24, 2026 15:06
@changeset-bot
Copy link

changeset-bot bot commented Mar 24, 2026

🦋 Changeset detected

Latest commit: 24e7e08

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@godaddy/react Patch
nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pbennett1-godaddy pbennett1-godaddy self-assigned this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant