Skip to content

Authentication, analytics, subscriptions dashboard, and UI overhaul#4

Merged
devcedrick merged 14 commits into
mainfrom
develop
Jul 19, 2026
Merged

Authentication, analytics, subscriptions dashboard, and UI overhaul#4
devcedrick merged 14 commits into
mainfrom
develop

Conversation

@devcedrick

@devcedrick devcedrick commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

This PR brings 14 commits spanning authentication, analytics, subscriptions management, currency utilities, and significant UI improvements to the home screen.

Features

  • Clerk Authentication — Full sign-in, sign-up, MFA (email code), forgot password flow, and session management
  • PostHog Analytics — Client-side event tracking for sign-in, sign-up, sign-out, password reset, subscription creation, and screen views
  • Home Dashboard — Displays user greeting, balance card, active subscriptions, and upcoming renewals
  • Subscriptions List — Dedicated tab with search filtering, expandable cards, and empty state
  • Create Subscription Modal — In-app form with name, price, frequency (monthly/yearly), and category picker
  • Currency UtilitiesformatCurrency with live USD-to-PHP conversion using ExchangeRate-API
  • Date & Status Helperslib/utils/date.ts and lib/utils/status.ts

Fixes

  • Optional chaining on Clerk errors access to prevent runtime crashes during transient hook states
  • Splash screen stays visible until custom fonts are fully loaded
  • LayoutWrap hoisted outside component to prevent remount on every render

UI / Styling

  • Custom tab bar with nativewind-styled components
  • Global CSS overhaul with auth, home, and modal design tokens
  • SafeAreaView consistency across all screens
  • Custom font registration (sans-regular, sans-medium, sans-semibold, sans-bold)

New Dependencies

  • posthog-react-native ^4.55.0
  • react-native-svg 15.12.1

Summary by CodeRabbit

  • New Features
    • Added a “Create Subscription” modal to add provider, price, monthly/yearly billing, and category.
    • Delivered the full subscriptions experience: searchable list, expandable cards, empty state, subscription details screen, and live in-app updates.
  • Analytics
    • Added PostHog tracking across sign-up/sign-in, password reset steps, sign-out, screen navigation, and subscription interactions/details.
    • Automatically disables analytics when PostHog isn’t configured.
  • Chores
    • Updated app icons/splash/metadata and added EAS configuration; refreshed Expo/React-related dependencies.

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
@devcedrick
devcedrick requested review from Copilot and removed request for Copilot July 13, 2026 10:44
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d52c7ec9-ea76-4d1f-8332-b59ba1df52ec

📥 Commits

Reviewing files that changed from the base of the PR and between f4c4390 and 6454bc6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Analytics foundation

Layer / File(s) Summary
PostHog configuration and provider wiring
app.config.js, app.json, eas.json, lib/config/posthog.ts, package.json, app/_layout.tsx
Expo and EAS configuration expose PostHog settings, the client is initialized with disabled-mode handling, dependencies are added, and the root layout provides screen and user tracking.

Authentication and account events

Layer / File(s) Summary
Authentication and account event tracking
app/(auth)/sign-in.tsx, app/(auth)/sign-up.tsx, app/(tabs)/settings.tsx, app/(tabs)/subscriptions/[id].tsx
Sign-in, sign-up, password reset, sign-out, and subscription detail viewing capture PostHog events.

Subscription management

Layer / File(s) Summary
Subscription creation and live updates
components/CreateSubscriptionModal.tsx, constants/data.ts, app/(tabs)/index.tsx
The creation modal validates and persists subscriptions, emits an event, and updates subscribed screens through an in-memory listener set.
Subscription list and expansion UI
app/(tabs)/subscriptions.tsx
The subscriptions tab filters live data, renders subscription cards and empty states, and manages expanded cards and keyboard dismissal.

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
Loading

Possibly related PRs

  • devcedrick/subora#2: Reworks the subscriptions dashboard and base subscription data used by these subscription UI and update changes.
  • devcedrick/subora#3: Implements the related Clerk-based authentication flows instrumented by these PostHog events.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title reflects the main themes of the PR: authentication, analytics, subscriptions, and UI updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
app/(tabs)/index.tsx (1)

35-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated manual external-store subscription — consider useSyncExternalStore. Both screens reimplement the same useEffect-registers-listener + useState-holds-snapshot boilerplate against the same subscribeToSubscriptions store. React's useSyncExternalStore is designed for exactly this and avoids potential tearing under concurrent rendering; exporting a getSubscriptionsSnapshot alongside subscribeToSubscriptions in constants/data.ts would let both sites collapse to a single hook call.

  • app/(tabs)/index.tsx#L35-L39: replace the useEffect/useState pair with useSyncExternalStore(subscribeToSubscriptions, getSubscriptionsSnapshot).
  • app/(tabs)/subscriptions.tsx#L24-L28: same replacement, reusing the same getSubscriptionsSnapshot export.
🤖 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 win

Weak ID generation for new subscriptions.

Math.random().toString(36).substring(7) has low entropy and no collision check; this value is used as the FlatList keyExtractor key downstream, so a collision would cause duplicate-key rendering issues. Prefer a proper UUID (e.g. expo-crypto's randomUUID() or the crypto.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

📥 Commits

Reviewing files that changed from the base of the PR and between 1dbdd00 and 79fe0c8.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • app.config.js
  • app/(auth)/sign-in.tsx
  • app/(auth)/sign-up.tsx
  • app/(tabs)/index.tsx
  • app/(tabs)/settings.tsx
  • app/(tabs)/subscriptions.tsx
  • app/(tabs)/subscriptions/[id].tsx
  • app/_layout.tsx
  • components/CreateSubscriptionModal.tsx
  • constants/data.ts
  • lib/config/posthog.ts
  • package.json

Comment thread app/_layout.tsx
Comment thread app/(tabs)/settings.tsx Outdated
Comment thread app/(tabs)/subscriptions.tsx
Comment thread components/CreateSubscriptionModal.tsx
Comment thread components/CreateSubscriptionModal.tsx Outdated
Comment thread components/CreateSubscriptionModal.tsx Outdated
Comment thread components/CreateSubscriptionModal.tsx Outdated
Copilot AI review requested due to automatic review settings July 17, 2026 10:58

This comment was marked as low quality.

- 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.
@devcedrick
devcedrick merged commit 5ebccc4 into main Jul 19, 2026
1 check passed
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.

2 participants