Authentication, analytics, subscriptions dashboard, and UI overhaul#4
Conversation
Add PostHog client configuration and instrument key user events: - sign-in (password, MFA), sign-up, sign-out, password reset flow - screen view tracking via _layout.tsx AppContent - subscription card expand and detail view events - user identification on auth state change Dependencies: posthog-react-native ^4.55.0, react-native-svg 15.12.1
Replace placeholder screen with a full FlatList backed by HOME_SUBSCRIPTIONS data, including search filtering, expand/collapse interactions, keyboard dismissal, and a proper empty state.
- Introduce CreateSubscriptionModal with name, price, frequency, and category fields - Wire up pub/sub pattern in constants/data.ts (addSubscription / subscribeToSubscriptions) - Both home and subscriptions screens now reactively reflect new subscriptions
|
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:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds PostHog configuration and analytics tracking across authentication, navigation, account actions, and subscription views. It also implements subscription creation, in-memory updates, modal entry, filtering, and expandable subscription cards. ChangesAnalytics foundation
Authentication and account events
Subscription management
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant CreateSubscriptionModal
participant SubscriptionData
participant HomeScreen
participant PostHog
User->>CreateSubscriptionModal: submit subscription form
CreateSubscriptionModal->>SubscriptionData: addSubscription(subscription)
SubscriptionData->>HomeScreen: notify subscribed screens
CreateSubscriptionModal->>PostHog: capture subscription_created
CreateSubscriptionModal-->>User: close modal
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
app/(tabs)/index.tsx (1)
35-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated manual external-store subscription — consider
useSyncExternalStore. Both screens reimplement the sameuseEffect-registers-listener +useState-holds-snapshot boilerplate against the samesubscribeToSubscriptionsstore. React'suseSyncExternalStoreis designed for exactly this and avoids potential tearing under concurrent rendering; exporting agetSubscriptionsSnapshotalongsidesubscribeToSubscriptionsinconstants/data.tswould let both sites collapse to a single hook call.
app/(tabs)/index.tsx#L35-L39: replace theuseEffect/useStatepair withuseSyncExternalStore(subscribeToSubscriptions, getSubscriptionsSnapshot).app/(tabs)/subscriptions.tsx#L24-L28: same replacement, reusing the samegetSubscriptionsSnapshotexport.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/`(tabs)/index.tsx around lines 35 - 39, Replace the manual useEffect/useState subscription logic with useSyncExternalStore using subscribeToSubscriptions and a shared getSubscriptionsSnapshot exported from constants/data.ts. Apply this change in app/(tabs)/index.tsx lines 35-39 and app/(tabs)/subscriptions.tsx lines 24-28, preserving the current subscription snapshot behavior in both screens.components/CreateSubscriptionModal.tsx (1)
80-80: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winWeak ID generation for new subscriptions.
Math.random().toString(36).substring(7)has low entropy and no collision check; this value is used as the FlatListkeyExtractorkey downstream, so a collision would cause duplicate-key rendering issues. Prefer a proper UUID (e.g.expo-crypto'srandomUUID()or thecrypto.randomUUID()global if available in your RN runtime).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/CreateSubscriptionModal.tsx` at line 80, Replace the weak identifier generation in the new subscription creation flow with a UUID generator, using the project’s available runtime or dependency such as expo-crypto randomUUID or crypto.randomUUID. Keep the generated UUID assigned to the subscription id used by the FlatList keyExtractor.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/_layout.tsx`:
- Around line 21-24: Update the PostHog call in the screen-tracking effect
around posthog.screen so it no longer spreads the full params object. Construct
the properties from an explicit allowlist of required screen fields, while
preserving previous_screen and excluding arbitrary deep-link values such as
tokens, codes, invites, and PII.
In `@app/`(tabs)/settings.tsx:
- Around line 35-39: Update handleSignOut so await signOut() completes before
calling posthog.capture("user_signed_out") and posthog.reset(); keep both
PostHog operations in the successful sign-out path so a rejected signOut leaves
analytics state unchanged.
In `@app/`(tabs)/subscriptions.tsx:
- Around line 34-36: Update the subscriptions screen’s handlePress to emit
posthog.capture("subscription_card_expanded", { subscription_id: id }) only when
the card transitions from collapsed to expanded, matching the tracking behavior
in the Home screen while preserving the existing toggle logic.
In `@components/CreateSubscriptionModal.tsx`:
- Around line 58-64: Update resetForm in CreateSubscriptionModal to also reset
isCategoryDropdownOpen to its closed state, ensuring reopening the mounted modal
does not show the category dropdown expanded.
- Around line 71-74: Strengthen the price validation in the
CreateSubscriptionModal submission flow so only finite, strictly positive
numeric values are accepted. Update the existing check around price.trim() and
Number(price) to reject zero, negative values, and Infinity before adding
entries to HOME_SUBSCRIPTIONS, while preserving the current invalid-price error
and early return.
- Around line 79-96: Update the newSub declaration in the subscription creation
flow to use the Subscription type instead of any, preserving the existing field
values and object construction while restoring compile-time validation against
the Subscription interface.
- Around line 110-114: Add an onRequestClose handler to the Modal component in
CreateSubscriptionModal, reusing the modal’s existing close or visibility-update
callback so Android hardware back dismisses it and the modal remains
warning-free.
---
Nitpick comments:
In `@app/`(tabs)/index.tsx:
- Around line 35-39: Replace the manual useEffect/useState subscription logic
with useSyncExternalStore using subscribeToSubscriptions and a shared
getSubscriptionsSnapshot exported from constants/data.ts. Apply this change in
app/(tabs)/index.tsx lines 35-39 and app/(tabs)/subscriptions.tsx lines 24-28,
preserving the current subscription snapshot behavior in both screens.
In `@components/CreateSubscriptionModal.tsx`:
- Line 80: Replace the weak identifier generation in the new subscription
creation flow with a UUID generator, using the project’s available runtime or
dependency such as expo-crypto randomUUID or crypto.randomUUID. Keep the
generated UUID assigned to the subscription id used by the FlatList
keyExtractor.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 98bf6b63-fc1c-43bd-8728-493d496f05d0
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (12)
app.config.jsapp/(auth)/sign-in.tsxapp/(auth)/sign-up.tsxapp/(tabs)/index.tsxapp/(tabs)/settings.tsxapp/(tabs)/subscriptions.tsxapp/(tabs)/subscriptions/[id].tsxapp/_layout.tsxcomponents/CreateSubscriptionModal.tsxconstants/data.tslib/config/posthog.tspackage.json
…ensitive deep-link data
- Fix expo-dev-client from ^57.0.5 to ~6.0.21 (wrong SDK version) - Fix expo-secure-store from ^57.0.0 to ~15.0.8 (wrong SDK version) - Regenerate package-lock.json with npm install - Set Node version to 22.14.0 in eas.json and .nvmrc for CI compatibility
The SDK 54 image provides Node 20.19.4 by default. Specifying 22.14.0 is not available on that image and caused the build to fail.
The .nvmrc specified Node 22.14.0 which isn't available on the SDK 54 build image, causing install dependencies phase to fail.
@clerk/react@6.12.5 requires react@~19.1.4 (>=19.1.4), but 19.1.0 was pinned. This caused npm ci to fail during EAS Build due to unresolvable peer dependency. Upgrading to 19.2.7 resolves this.
Summary
This PR brings 14 commits spanning authentication, analytics, subscriptions management, currency utilities, and significant UI improvements to the home screen.
Features
formatCurrencywith live USD-to-PHP conversion using ExchangeRate-APIlib/utils/date.tsandlib/utils/status.tsFixes
errorsaccess to prevent runtime crashes during transient hook statesLayoutWraphoisted outside component to prevent remount on every renderUI / Styling
New Dependencies
posthog-react-native^4.55.0react-native-svg15.12.1Summary by CodeRabbit