chore(pos): design review — POS app redesign & polish - #596
Conversation
- Update accent color to #0666FF across light/dark palettes - Add foreground-primary-fix so cards/keyboard read against the dark bg - Add new splash logos (incl. Android-specific) and icon assets - Copy and layout polish across home, scan, payment, and settings screens Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop all branded wallet theme variants and the Settings picker, leaving the app on the default theme. The variant machinery (Variant type, Variants record, VariantList, store field, receipt/header logo hooks) is kept so a variant can be re-added later; a comment in variants.ts documents the steps. - Narrow VariantName to "default" and reduce Variants to the default entry - Remove the "Wallet theme" SettingsItem, its bottom sheet, and lock logic - Simplify getMergedTheme to return the base palette (merge kept as a comment) - Bump settings persist version to 17, migrating stale variants to default - Delete branded brand PNGs and the unused MONEY2020 printer logo - Update store tests for default-only + a migration reset test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add SuccessAnimation Skottie component (Success.json), a one-shot loader that holds on its final frame, shown above the amount on the payment-success screen - Drop per-route header helpers; render HeaderImage through a single screenOptions title callback and narrow its tintColor typing - Refine payment error copy and payment success/failure screen theming - Sync stale test expectations (payment-errors copy, credential logs) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a payment fails with invalid_api_key, retrying just loops back into a
flow that will fail again — the terminal needs its API key fixed. Swap the
failure CTA to "Go to Settings" and navigate to the Settings screen for that
error; all other errors keep the "Start new payment" behavior.
- Add exported INVALID_API_KEY constant in utils/payment-errors.ts
- Branch the failure CTA label + handler on the errorCode param
- Exit the payment flow via dismissAll() then push("/settings") so Back → Home
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Disable NFC/HCE tap-to-pay by default via a single build-time flag so it can be re-enabled without code changes. - add utils/feature-flags.ts exposing isNfcHceEnabled from EXPO_PUBLIC_NFC_HCE_ENABLED - add plugins/withHceFeatureFlag.js to inject a matching HCE_ENABLED <meta-data> into the AndroidManifest; register it in app.json - gate scan-screen HCE activation/UI and the settings toggle on the flag - guard both setActivity (setPreferredService) and enable() in HceModule so a disabled build never registers as an HCE handler - remove dangling ./assets/images/variants entry that broke prebuild - replace nfc.png with a smaller icon to fix downscaling artifacts Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Override the global WPay logo headerTitle with themed text titles on the settings and activity screens. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Override the global WPay logo headerTitle with a themed text title on the logs screen, matching Settings and Transactions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Log successful requests as "<METHOD> <path>" instead of the identical "API request successful", and mask id-like path segments to ":id" so titles stay short and group by route. Extract maskPathIds into utils/api with tests; keep the full endpoint + method in the log data. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rmation Add a centered empty state, redesign log cards with per-level badges and tap-to-expand JSON (data-bearing entries only), pin the Clear logs button to the bottom, and gate clearing behind a confirmation bottom sheet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BLUETOOTH_CONNECT is an Android 12+ runtime permission with no iOS/web handler, so requesting it unconditionally crashed the iOS Simulator with "No permission handler detected". Only request it on Android; iOS relies on the NSBluetoothAlwaysUsageDescription auto-prompt and web is stubbed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rework the toast to match the WalletConnect Library Figma design: - Content-hugging pill (radius 64) with the label on the left and a 28px circular status badge on the right; soft drop shadow, no border. - Inverted surface: bg-invert + text-invert, so the toast reads as a black pill in light mode and a white pill in dark mode. - Per-type badges (info/warning/error/success) exported from Figma, plus a loading variant backed by ActivityIndicator. - Fix toastConfig so each type renders its own visual (info/warning were previously mismapped to success/error). - Label shrinks and the badge holds its size so long, wrapping messages no longer push the icon out of view. - Move the toast host to the top with a safe-area-aware topOffset. - Drop image assets no longer referenced anywhere (check_circle, error, clock, scan, wallet). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a compact "Copy entry" pill to each log card header; tapping it copies the entry to the clipboard as structured JSON (type/date/location/message/ body, full date with year) and shows a confirmation toast. - Add an optional compact size to the shared Button (size="sm"); defaults to the existing size so other call sites are unaffected. - Right-align the copy button by lifting the card header to a full-width row. - Extract log helpers to utils/logs.ts (formatTimestamp, formatFullTimestamp, buildLogText) and the card into components/log-card.tsx (memoized), slimming app/logs.tsx to the screen concern. - Give the Logs header title component a display name (react/display-name). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a "Type" (All/Info/Error) and "Date" (all time/today/7 days/this week/ this month) filter bar with a divider above the logs list, reusing the Transactions filter building blocks (FilterButtons, SettingsBottomSheet, RadioList, getDateRange). - Generalize FilterButtons to a neutral buttons array so both screens share it; update the Activity call site. Lift DATE_RANGE_OPTIONS into utils/date-range. - Persist logLevelFilter/logDateRangeFilter in the logs store; clearLogs resets them to defaults. Filter logs client-side via filterLogs (info also matches the never-emitted "log" level, consistent with the card badge). - Hide the filter bar entirely when there are no logs; show a "No matching logs" empty state when filters exclude everything. Info radio dot uses bg-invert to match the Info badge. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add optional subtitle prop to SettingsBottomSheet and use it on the Merchant ID sheet to explain where to find the ID. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reorganize the Settings screen to match the new design: group rows under
Terminal, Connection and a conditional Security section, each with a section
header. Theme/Currency keep the up-down caret; Merchant ID / Customer API key
now use a right chevron. The logs entry becomes a row showing the entry count
with a dark "View Logs" pill (the whole row is pressable). "Print test
receipt" moves to a button pinned at the bottom with a printer icon, hidden
on web where printing is unsupported.
- add SettingsSection wrapper and LogEntriesRow components (+ test)
- add caret variant ("up-down" | "right") to SettingsItem
- add bolder chevron-right asset for drill-in rows and the pill
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- fix "Clear logs" button overflowing the right edge (wrap in a padded footer instead of horizontal margins on a full-width button) - add a "Clear filters" CTA to the no-results empty state and keep the filters visible so users can recover - hide the "Clear logs" button when the active filters match no logs, since it clears all logs and reads as confusing over an empty result - tune the FlatList for low-end hardware (initialNumToRender, windowSize, maxToRenderPerBatch) without getItemLayout, since log cards have variable heights and expand on tap; skip removeClippedSubviews to avoid blank cells on fast Android scrolling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Transaction card: leading status icon square, status label as colored title, date subtitle, trailing amount + chevron - Add per-status icons/colors (Pending, Confirmed, Cancelled, Failed, Expired) via shared getTransactionStatusMeta single source of truth - Filters: transparent + bordered chips (shared, also applies to Logs); divider under the filter row; filters pinned above the scrolling list - Empty states: filtered "No payments found" + Clear filters; empty view is centered and non-scrollable - Detail modal: status pill now shows the status icon; Payment ID and Transaction ID render in KH Teka Mono + copy icon and are shortened - Unify date format to "14 Oct 2025 - 14:45" across cards, modal and Logs - Add KH Teka Mono font, icon-warning theme token and status icon assets - Logs: use plain RN Pressable on expandable cards so scrolling an open entry no longer fights the press animation Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hide the header back button and disable swipe-back while a payment is
confirming on the scan screen, and disable swipe-back on the terminal
payment-success/payment-failure screens.
The hidden state is derived from the payment status rather than toggled
at navigation time: a terminal status flips the loading state off and
navigates away in the same tick, and reviving the native back-button
config mid-detach crashes react-native-screens on Android
("ScreenStackFragment added into a non-stack container").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The expanding circle is sized from the screen diagonal but was centered on the padded container, so the status-bar inset pushed its center below the true screen center and left the top corners uncovered. Move the safe-area/horizontal padding onto the content layer so the circle centers on the real screen center, and add a little scale headroom. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
Claude finished @ignaciosantise's task in 4m 13s —— View job Code Review
🚨 PR Too Large This PR mixes design system refactor, NFC feature flag, variant removal, and 3 screen redesigns. Suggested split:
Found 6 issue(s)Issue 1: Full API response bodies (with transaction/wallet data) logged without filtering or retention capID: dcl-client-response-data-in-logs-c7e1 Context:
Recommendation: Strip or mask Issue 2:
|
|
Re: finding #6 ( |
…lor) - _layout: build header titles once at module scope so headerTitle keeps a stable identity and no longer remounts/flickers on RootLayout re-render. - payment-success: merge the two identical-delay reveal timers into one. - settings: drop the ignored tintColor from the printer image style array. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Design-review pass for dapps/pos-app, focusing on UI polish and flow robustness while adding better logging/filters, unified components (button/pressable/toast), and feature-gating for NFC/HCE to avoid platform edge cases.
Changes:
- Redesigned Logs/Settings/Transactions UI building blocks (new cards, filters, sections, modals) and centralized transaction-status display metadata.
- Refreshed theming and component primitives (new
Button, sharedPressable, updated toast behavior/positioning, contrast tweaks). - Added build-time NFC/HCE kill-switch (JS + config plugin + native Android module gating) and improved logging (masked API paths, log filters).
Reviewed changes
Copilot reviewed 63 out of 99 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| dapps/pos-app/utils/types.ts | Adds log-level filter type used by Logs UI/store. |
| dapps/pos-app/utils/transaction-status.ts | Centralizes transaction status → label/color/icon mapping. |
| dapps/pos-app/utils/toasts.tsx | Expands toast types (info/warning/loading) and fixes mappings. |
| dapps/pos-app/utils/printer.ts | Guards Android-only Bluetooth permission request by platform. |
| dapps/pos-app/utils/payment-errors.ts | Refines payment error copy and exports INVALID_API_KEY. |
| dapps/pos-app/utils/payment-errors.test.ts | Updates tests to match revised payment error messages. |
| dapps/pos-app/utils/navigation.ts | Simplifies reset navigation to dismissTo behavior. |
| dapps/pos-app/utils/misc.ts | Improves date formatting and adds spoken countdown formatter. |
| dapps/pos-app/utils/misc.test.ts | Updates/extends tests for countdown formatting changes. |
| dapps/pos-app/utils/logs.ts | Adds log formatting, filtering, and copy serialization helpers. |
| dapps/pos-app/utils/feature-flags.ts | Introduces build-time NFC/HCE feature flag helper. |
| dapps/pos-app/utils/date-range.ts | Extracts shared date-range options for filters. |
| dapps/pos-app/utils/api.ts | Adds URL path ID-masking helper for safer logging. |
| dapps/pos-app/utils/api.test.ts | Adds test coverage for maskPathIds. |
| dapps/pos-app/store/useSettingsStore.ts | Updates defaults/migrations (variant removal, date filter reset) and bumps persist version. |
| dapps/pos-app/store/useLogsStore.ts | Adds persisted log filters and actions; resets filters on clear. |
| dapps/pos-app/services/client.ts | Improves API logging (method + masked endpoint) and includes method in error logs. |
| dapps/pos-app/plugins/withHceFeatureFlag.js | Injects AndroidManifest meta-data for native HCE feature gating. |
| dapps/pos-app/modules/hce/android/src/main/java/com/reown/mobilepos/hce/HceModule.kt | Gates native HCE enable/disable behavior on manifest flag. |
| dapps/pos-app/jest.setup.js | Removes unused WC project env var from test setup. |
| dapps/pos-app/hooks/use-theme-color.ts | Disables variant color merging and uses base palette only. |
| dapps/pos-app/hooks/use-merchant-flow.ts | Reuses formatCountdown for lockout messaging. |
| dapps/pos-app/constants/variants.ts | Reduces shipped variants to default while preserving structure for future re-enable. |
| dapps/pos-app/constants/theme.ts | Refreshes accent colors, adds warning token, and improves dark surface contrast token. |
| dapps/pos-app/constants/printer-logos.ts | Removes Money20/20 printer logo constant, leaving default logo. |
| dapps/pos-app/components/transaction-detail-modal.tsx | Improves copy affordances, truncation, and moves toast to top with safe-area offset. |
| dapps/pos-app/components/transaction-card.tsx | Redesigns transaction card layout and uses status meta + updated date formatting. |
| dapps/pos-app/components/toast.tsx | Redesigns toast UI, adds loading state, and new icon assets. |
| dapps/pos-app/components/success-animation.tsx | Adds Skia-based one-shot success animation with pause/resume behavior. |
| dapps/pos-app/components/status-badge.tsx | Uses shared status meta and new badge icon behavior. |
| dapps/pos-app/components/settings-section.tsx | Introduces grouped Settings section wrapper component. |
| dapps/pos-app/components/settings-item.tsx | Adds caret variants and migrates interaction to shared Pressable. |
| dapps/pos-app/components/settings-bottom-sheet.tsx | Adds optional subtitle and updates close affordance. |
| dapps/pos-app/components/radio-list.tsx | Uses updated surface token for unselected rows. |
| dapps/pos-app/components/pressable.tsx | Adds shared Pressable wrapper around pressto with a11y wiring. |
| dapps/pos-app/components/pressable.test.tsx | Adds unit coverage for new Pressable wrapper. |
| dapps/pos-app/components/pin-modal.tsx | Updates key/cancel button styling to align with new surface tokens. |
| dapps/pos-app/components/numeric-keyboard.tsx | Migrates keys to shared Pressable and updated surface token. |
| dapps/pos-app/components/log-entries-row.tsx | Adds Settings “View logs” row with count + pill CTA. |
| dapps/pos-app/components/log-entries-row.test.tsx | Tests log entries row rendering and interaction. |
| dapps/pos-app/components/log-card.tsx | Adds expandable log card with copy/share affordance and animations. |
| dapps/pos-app/components/filter-buttons.tsx | Generalizes filter buttons to a config array and new styling. |
| dapps/pos-app/components/empty-state.tsx | Updates CTA handling to use new Button API and styling. |
| dapps/pos-app/components/clear-logs-modal.tsx | Adds “clear logs” confirmation bottom sheet modal. |
| dapps/pos-app/components/card.tsx | Migrates pressable card behavior to shared Pressable. |
| dapps/pos-app/components/button.tsx | Replaces prior generic pressable button with a themed, typed Button component. |
| dapps/pos-app/components/button.test.tsx | Adds unit coverage for new Button variants/sizing/disabled state. |
| dapps/pos-app/assets/lottie/Success.json | Adds new success animation asset. |
| dapps/pos-app/assets/images/wc-logo-dark.png | Adds/updates WalletConnect logo asset naming. |
| dapps/pos-app/app/settings.tsx | Redesigns Settings layout into sections; adds logs row; gates NFC; adds footer print action. |
| dapps/pos-app/app/scan.tsx | Gates NFC/HCE by feature flag; improves a11y countdown announcements; adjusts header back/gestures. |
| dapps/pos-app/app/payment-success.tsx | Updates success screen animation layering, safe-area handling, and new success animation. |
| dapps/pos-app/app/payment-failure.tsx | Routes invalid API key failures to Settings; updates visuals and Button usage. |
| dapps/pos-app/app/logs.tsx | Redesigns logs screen with filters, empty states, and clear confirmation flow. |
| dapps/pos-app/app/index.tsx | Redesigns home actions with responsive layout and improved a11y labels/hints. |
| dapps/pos-app/app/amount.tsx | Migrates primary CTA to new Button API and simplifies styling. |
| dapps/pos-app/app/activity.tsx | Uses shared date-range options and redesigned filters/empty states. |
| dapps/pos-app/app/_layout.tsx | Updates headers, toast placement, adds mono font, and disables gestures on terminal screens. |
| dapps/pos-app/app.json | Adds HCE feature-flag plugin, new splash assets, and registers mono font assets. |
| dapps/pos-app/AGENTS.md | Updates agent guidance to reflect variant removal and refreshed project notes. |
| dapps/pos-app/.env.example | Adds NFC/HCE build-time flag env var; removes WC project id. |
| dapps/pos-app/tests/store/useSettingsStore.test.ts | Updates variant-related tests and adds migration coverage. |
| dapps/pos-app/tests/services/client.test.ts | Updates expectations for new API success log message/data. |
| dapps/pos-app/tests/hooks/use-url-credentials.test.ts | Updates log-count expectations for additional “Credentials updated” log. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Move Face ID + NFC toggles into Connection (drop Security section) - Add reusable SettingsToggleItem with inline title/description - Add Device section: Logs as an icon item row + Print test receipt button - Redesign Logs row (terminal icon + entries count + chevron), remove LogEntriesRow - Support optional leading icon in SettingsItem; drop fixed footer Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ial handling - Add amber "Finish setting up" banner with an "N Left" counter, shown while a required credential is missing - Flag unconfigured Merchant ID / Customer API key rows with an orange bullet and a "Not set" badge (new Badge + SetupBanner components; reuse icon-warning, add bg-warning token) - Support optional bullet + badge on SettingsItem - Clearing the merchant ID no longer resets to env defaults, and no longer clears the customer API key (independent credentials) - Allow saving an empty customer API key to clear it (enable Save when the masked field is emptied), tracked via isEditingCustomerApiKey - Persist a hasInitializedDefaults flag (store v19) so env defaults seed only on first run and are never re-applied after manual clear/change Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- transaction-status: correct doc comment (PaymentStatus -> TransactionStatus) - toast: use theme icon-accent-primary for the loading spinner instead of the stale hard-coded accent (#0988F0) - pressable.test: mock PressableScale to honor `enabled`, and assert a disabled press does not fire onPress (was testing the mock, not real behavior) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The accessibility labels added in 949c8ba render as aria-label on web, which Maestro's `id:` selector resolves BEFORE data-testid — so every id-selected element (start-payment-button, charge-button, cancel-button, pos-qr-code, etc.) became unmatchable and the whole web E2E suite failed. Add a web-only MutationObserver that mirrors data-testid onto the DOM id (checked first by Maestro), restoring id matching without dropping the accessibility labels. Mirrors the existing rn_cli_wallet bridge. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test mocked `pressto`'s PressableScale, so it only exercised the mock, not the real press/disabled behavior. It added no meaningful coverage over the trivial prop-forwarding wrapper — remove it rather than assert against a mock. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cap the primary action button's height at ~1.3x its width so tall screens no longer stretch it into a long rectangle. Bottom-anchor the home actions so the reclaimed space falls at the top, keeping the button visually centered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The near-square cap was computed from useWindowDimensions().width, which on the web build isn't the button's real width (the app renders inside a device frame), so the cap never applied and the button stretched full-height. Measure the container's content width via onLayout and cap the height from that instead, so the rule holds on web and native alike. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Overview
Design-review pass across the pos-app: redesigns and polish for the Logs, Settings, Transactions and payment flows, plus a batch of fixes for theming, accessibility and native-navigation edge cases.
Highlights
Screens & flows
Fixes & polish
ScreenStackFragment added into a non-stack container)invalid_api_keypayment failureEXPO_PUBLIC_NFC_HCE_ENABLEDNotes
Opened as a draft for review. See individual commits for scoped changes.
🤖 Generated with Claude Code