Conversation
🦋 Changeset detectedLatest commit: 5b91963 The changes in this PR will be included in the next version bump. 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 |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughComprehensive feature release introducing installments/pay-later payment modes, redesigned home screen with new CardStatus and PortfolioSummary components, font unification to SplineSans, widespread design token standardization across spacing, new payment-related UI sheets, hook refactoring, and Spanish translation expansion. Includes Maestro E2E test updates validating new payment flows. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Home as Home Component
participant CardStatus as CardStatus Component
participant PayModeSheet as PayModeSheet
participant InstallmentsSheet as InstallmentsSheet
participant useInstallmentRates as useInstallmentRates Hook
participant mutateMode as setCardMode Mutation
participant Backend as Backend API
User->>Home: Opens Home Screen
Home->>CardStatus: Renders with mode, collateral, creditLimit
User->>CardStatus: Taps "Now/Later" Toggle
CardStatus->>PayModeSheet: Opens mode selection
User->>PayModeSheet: Selects "Pay Later"
PayModeSheet->>CardStatus: Calls onModeChange
CardStatus->>InstallmentsSheet: Opens installment selector
User->>InstallmentsSheet: Selects installment count
InstallmentsSheet->>useInstallmentRates: Requests APR for selection
useInstallmentRates->>Backend: Queries market data
Backend-->>useInstallmentRates: Returns rates, utilization
useInstallmentRates-->>InstallmentsSheet: Returns payment schedule
InstallmentsSheet->>User: Displays APR and payments
User->>InstallmentsSheet: Confirms installment count
InstallmentsSheet->>mutateMode: Calls onModeChange(installmentCount)
mutateMode->>Backend: POST card mode change
Backend-->>mutateMode: Confirms update, returns new limits
mutateMode->>Home: Updates state optimistically
Home->>CardStatus: Re-renders with new mode/limits
CardStatus-->>User: Displays updated spending limit
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @dieguezguille, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request delivers a comprehensive redesign of the application's core user interface, specifically targeting the home and payments sections. The changes aim to modernize the application's appearance, improve navigation, and introduce new functionalities such as an installments calculator and enhanced card management options. The update focuses on providing a more intuitive and visually appealing experience for users interacting with their financial data and card services. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
❌ 1 Tests Failed:
View the top 1 failed test(s) by shortest run time
To view more test analytics, go to the Prevent Tests Dashboard |
Greptile Summaryredesigned home screen with new installments payment system and visual refresh
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
Start[User opens Home screen] --> CardStatus[CardStatus Component]
CardStatus --> Toggle{Pay Mode Toggle}
Toggle -->|Now mode = 0| DebitView[Shows Spending Limit]
Toggle -->|Later mode > 0| CreditView[Shows Credit Limit]
Toggle --> InstallmentsButton[User taps Later toggle]
InstallmentsButton -->|mode = 0| SetMode[Set mode to lastInstallments ?? 1]
InstallmentsButton -->|mode > 0| OpenSheet[Open InstallmentsSheet]
OpenSheet --> SelectInstallments[InstallmentsSheet]
SelectInstallments --> LoadRates[useInstallmentRates hook]
LoadRates --> CalcRates[Calculate APR for 1-12 installments]
CalcRates --> Display[Display horizontal scroll cards]
Display --> UserSelect[User selects installment count]
UserSelect --> UpdateMode[Call onModeChange with selected count]
UpdateMode --> MutateMode[mutateMode API call]
MutateMode --> UpdateCache[Update queryClient cache]
CardStatus --> LearnMore[User taps Learn More]
LearnMore --> PayModeSheet[PayModeSheet Component]
PayModeSheet --> ExplainModes[Explain Now vs Later modes]
CreditView --> Payment[User makes purchase]
Payment --> CreateDebt[Debt created with maturity]
CreateDebt --> HomePayments[OverduePayments/UpcomingPayments]
HomePayments --> PaymentClick[User clicks payment]
PaymentClick --> PayComponent[Pay Component]
PayComponent --> AssetSelect[Select payment asset]
AssetSelect --> CalcRoute[Calculate swap route if needed]
CalcRoute --> RepayDebt[Execute repayAtMaturity]
Last reviewed commit: 1220ff6 |
| if (!formatted) { | ||
| return ( | ||
| <XStack alignItems="center" position="relative" {...properties}> | ||
| {children} | ||
| </XStack> | ||
| ); |
There was a problem hiding this comment.
🟡 Amount component ignores label prop in the children rendering path, making amounts inaccessible to screen readers
When the Amount component is used with children instead of the amount prop (i.e., amount is undefined), the label prop is destructured out but never applied to the fallback XStack wrapper. The children inside use aria-hidden, so screen readers cannot access the amount value at all.
Root Cause
The Amount component at src/components/shared/Amount.tsx:31-36 has two rendering paths:
- Formatted path (when
amountis provided): correctly appliesaria-label={hidden ? "***" : (label ?? ...)}andtabIndex={0}on line 47-48. - Children path (when
amountis undefined): renders a plainXStackwithoutaria-labelortabIndex, discarding thelabelprop entirely.
The LimitPaginator in src/components/home/CardStatus.tsx:250-263 and 282-295 uses the children path, passing label with the formatted dollar amount but no amount prop. The children (<Text aria-hidden ...>) are explicitly hidden from assistive technology. Since label is not forwarded, and tabIndex is not set, the spending limit and credit limit values are completely invisible to screen readers.
Impact: Users relying on screen readers cannot access spending limit or credit limit values on the home screen card status component.
| if (!formatted) { | |
| return ( | |
| <XStack alignItems="center" position="relative" {...properties}> | |
| {children} | |
| </XStack> | |
| ); | |
| if (!formatted) { | |
| return ( | |
| <XStack alignItems="center" position="relative" aria-label={hidden ? "***" : label} tabIndex={label ? 0 : undefined} {...properties}> | |
| {children} | |
| </XStack> | |
| ); | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
af0e857 to
dd8f188
Compare
| const { installments: payments, effectiveRate } = splitInstallments( | ||
| amount, | ||
| totalFloatingDepositAssets, | ||
| firstMaturity, | ||
| fixedPools.length, | ||
| poolUtilizations, | ||
| floatingUtilization, | ||
| marketUtilization, | ||
| parameters, | ||
| now, | ||
| ); |
There was a problem hiding this comment.
🚩 useInstallmentRates passes extra now argument to splitInstallments
In useInstallmentRates.ts:72-82, splitInstallments is called with 9 arguments (including now as the 9th), while the existing useInstallments.ts:34-52 calls it with only 8 arguments (no timestamp). If splitInstallments has an optional 9th timestamp parameter, then useInstallments may be relying on a default value while useInstallmentRates explicitly passes it — which would be the more correct usage. If there's no 9th parameter, the extra argument is silently ignored in JavaScript. Either way this isn't a runtime error, but the inconsistency between the two call sites is worth verifying against the @exactly/lib function signature.
Was this helpful? React with 👍 or 👎 to provide feedback.
| <Modal transparent visible animationType="fade" statusBarTranslucent> | ||
| <View style={StyleSheet.absoluteFill}> | ||
| <SVG width={screenWidth} height={screenHeight}> | ||
| <Defs> | ||
| <Mask id="cutout"> | ||
| <Rect width={screenWidth} height={screenHeight} fill="white" /> | ||
| <Rect | ||
| transform={[{ translateX: cutout.x }, { translateY: cutout.y }]} | ||
| width={cutout.width} | ||
| height={cutout.height} | ||
| rx={cutoutRadius} | ||
| fill="black" | ||
| /> | ||
| </Mask> | ||
| </Defs> | ||
| <Rect width={screenWidth} height={screenHeight} fill="rgba(0,0,0,0.56)" mask="url(#cutout)" /> | ||
| <Rect | ||
| transform={[{ translateX: cutout.x }, { translateY: cutout.y }]} | ||
| width={cutout.width} | ||
| height={cutout.height} | ||
| rx={cutoutRadius} | ||
| fill="none" | ||
| stroke="white" | ||
| strokeWidth={2} | ||
| /> | ||
| </SVG> | ||
| </View> | ||
| <Pressable | ||
| aria-label={t("Tap here to change the number of installments")} | ||
| style={[ | ||
| styles.cutoutPress, | ||
| { top: cutout.y, left: cutout.x, width: cutout.width, height: cutout.height, borderRadius: cutoutRadius }, | ||
| ]} | ||
| onPress={() => { | ||
| onPress(); | ||
| onDismiss(); | ||
| }} | ||
| /> | ||
| <Theme name="light"> | ||
| <YStack | ||
| position="absolute" | ||
| top={tooltipTop} | ||
| left={tooltipLeft} | ||
| width={200} | ||
| backgroundColor="$backgroundSoft" | ||
| borderRadius="$r3" | ||
| padding="$s4" | ||
| shadowColor="$uiNeutralSecondary" | ||
| shadowOffset={{ width: 0, height: 2 }} | ||
| shadowOpacity={0.15} | ||
| shadowRadius={8} | ||
| onPress={() => { | ||
| onPress(); | ||
| onDismiss(); | ||
| }} | ||
| > | ||
| <View | ||
| position="absolute" | ||
| top={-6} | ||
| left={arrowLeft} | ||
| width={12} | ||
| height={12} | ||
| backgroundColor="$backgroundSoft" | ||
| borderRadius={2} | ||
| transform={[{ rotate: "45deg" }]} | ||
| /> | ||
| <Text footnote textAlign="center"> | ||
| {t("Tap here to change the number of installments")} | ||
| </Text> | ||
| </YStack> | ||
| </Theme> | ||
| </Modal> | ||
| ); |
There was a problem hiding this comment.
🚩 InstallmentsSpotlight has no full-screen dismiss affordance
The InstallmentsSpotlight modal overlay renders an SVG mask with a cutout, a Pressable over the cutout area, and a tooltip — but there's no Pressable covering the rest of the screen for dismissal. Users can only dismiss by tapping the highlighted cutout or the tooltip, both of which also trigger onPress (opening the installments sheet). There's no way to simply dismiss the spotlight without also opening the sheet. This may be intentional (force engagement with the feature), but it could frustrate users who want to dismiss it.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b91963e64
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (mode > 0) onInstallmentsPress(); | ||
| else onModeChange(lastInstallments ?? 1); | ||
| }} |
There was a problem hiding this comment.
Initialize pay-later fallback from current card mode
When the card is already in Pay Later mode on first load, this toggle falls back to lastInstallments from local query state, but that state defaults to 1 unless a prior setCardMode mutation populated it. In the common case of a fresh install/cleared cache (or mode changed on another device), switching to Now and then tapping Later here will unexpectedly set mode 1 instead of restoring the user’s actual previous installment count from card.mode, changing repayment behavior silently.
Useful? React with 👍 / 👎.
| <YStack flex={1} padding="$s4" gap="$s4_5"> | ||
| <YStack flex={1} gap="$s4"> | ||
| <View flex={1} width="100%"> |
There was a problem hiding this comment.
Restore scrolling in connection sheet content
This sheet now uses a fixed-height YStack inside a 90% modal without a ScrollView, so on smaller devices or larger accessibility text sizes the combined illustration, disclaimer, terms, and CTA can exceed viewport height and push the action button out of reach. That blocks users from completing the connection flow in those contexts.
Useful? React with 👍 / 👎.
closes #501, closes #599, closes #713
Summary by CodeRabbit
New Features
Style & UI Improvements
Bug Fixes
Greptile Summary
this pr implements a comprehensive home screen redesign focused on the new pay mode selection feature, allowing users to toggle between instant payments (pay now/debit mode) and installment-based credit (pay later/credit mode). the changes introduce:
Amountcomponent, addedButtonColumnandButtonLabelvariants to styled button, redesigned portfolio summary with asset logo previewsthe implementation integrates with existing financial calculations from
@exactly/liband maintains consistency with the project's established patterns.Confidence Score: 4/5
useInstallmentRates.tsline 29 which has already been flagged in previous comments.Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Home Screen] --> B{Card Exists?} B -->|Yes| C[CardStatus Component] C --> D[Pay Mode Toggle] D --> E{User Selects Mode} E -->|Pay Now| F[Debit Mode - mode=0] E -->|Pay Later| G[Credit Mode - mode>0] G --> H[InstallmentsSheet] H --> I[useInstallmentRates Hook] I --> J[Calculate APR for 1-12 installments] J --> K[Display rates in scrollable cards] K --> L[User selects installment count] L --> M[Update card mode via setCardMode API] C --> N[LimitPaginator] N --> O{Mode Check} O -->|mode=0| P[Show Spending Limit] O -->|mode>0| Q[Show Credit Limit] D --> R[Learn More] R --> S[PayModeSheet] S --> T[Explain Pay Now vs Pay Later] A --> U[PortfolioSummary] U --> V[Display assets with Amount component] V --> W[Show APR & collateral]Last reviewed commit: b87e85f