Both left-pane buttons now functional. Cashier can find a customer by
scanning their loyalty QR or enroll a brand-new customer from the
tablet — closing the last gap in the everyday POS flow.
- TerminalViewModel: scannerOpen / enrollDialogOpen / enrolling /
enrollError state. submitEnroll posts to /cards/enroll, then re-fetches
the lookup shape so the customer pane renders fully (rewards,
cooldown). On lookup-after-enroll failure (rare) the new card_number
is pre-filled in the search field as a fallback.
- EnrollDialog.kt (new): AlertDialog with name + email (required), phone
+ birthday (optional; birthday is plain YYYY-MM-DD text — date picker
is a polish task). Inline error surface for backend rejections.
- QrScannerOverlay.kt (new): fullscreen overlay reusing QrScannerView
from Phase B. Cancel button top-right. Decoded value is treated as a
card_number and feeds the lookup flow.
- TerminalScreen: scan/enroll buttons are no longer disabled; the two
new composables render conditionally on top of the main layout.
The tablet now supports every everyday flow: lookup, scan, enroll,
stamp, earn points, redeem stamps, redeem reward, recent feed.
Verified by ./gradlew assembleDebug — clean build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>