Skip to content

feat(profile): add EnterInviteCodeSheet with keyboard handling#132

Merged
BillChirico merged 36 commits into
mainfrom
develop
Dec 11, 2025
Merged

feat(profile): add EnterInviteCodeSheet with keyboard handling#132
BillChirico merged 36 commits into
mainfrom
develop

Conversation

@BillChirico
Copy link
Copy Markdown
Member

@BillChirico BillChirico commented Dec 11, 2025

Summary

  • Create new EnterInviteCodeSheet component for sponsor invite code entry with proper keyboard handling
  • Add keyboard behavior props (keyboardBehavior, keyboardBlurBehavior) to GlassBottomSheet for interactive keyboard scrolling
  • Refactor profile.tsx to use sheet-based invite code entry instead of inline input
  • Update LogSlipUpSheet with same keyboard improvements
  • Add comprehensive test coverage for new sheet component (97.91% line coverage)

Changes

  • New Component: components/sheets/EnterInviteCodeSheet.tsx - Bottom sheet for entering sponsor invite codes with 8-character validation, auto-capitalization, and loading states
  • GlassBottomSheet Enhancement: Added keyboardBehavior and keyboardBlurBehavior props for configurable keyboard handling
  • Profile Refactor: Moved invite code input from inline to sheet-based approach for better keyboard UX on iOS
  • Tests: Added 29 new tests for EnterInviteCodeSheet covering rendering, validation, submission, and dismissal

Test plan

  • All 1495 tests pass
  • Test coverage meets 80% threshold (80.12% statements, 81.16% lines)
  • Format, lint, and typecheck pass
  • Manually tested on iOS simulator - keyboard expands sheet properly
  • Test on physical iOS device
  • Test on Android device/emulator

Note

Introduces a new EnterInviteCodeSheet and refactors profile to use it, while enhancing GlassBottomSheet keyboard/back behavior and updating related sheets, tests, and docs.

  • UI/Flows:
    • EnterInviteCodeSheet (components/sheets/EnterInviteCodeSheet.tsx): New bottom sheet for sponsor codes with 8-char validation, loading, and imperative API.
    • Profile (app/(tabs)/profile.tsx): Replaces inline invite input with sheet; updates joinWithInviteCode (uses user.id, throws errors for sheet to display); switches to KeyboardAwareScrollView; refines sobriety date pickers.
    • GlassBottomSheet (components/GlassBottomSheet.tsx): Adds keyboardBehavior/keyboardBlurBehavior; Android BackHandler integration; web Escape key handling; unified backdrop.
    • LogSlipUpSheet (components/sheets/LogSlipUpSheet.tsx): Uses BottomSheetTextInput; adopts new keyboard props; tweaks date picker dismissal.
  • Testing:
    • Adds comprehensive tests for EnterInviteCodeSheet; expands GlassBottomSheet (incl. Android back button); updates profile tests and adds keyboard-avoidance suite; extends jest.setup.js with BackHandler and document mocks; augments validation edge-case tests.
  • Docs:
    • Expands CLAUDE.md (TDD/CI/testing guidance); adds docs/plans/2025-12-11-toast-notifications-design.md.
  • Deps/Config:
    • Adjusts react-native-keyboard-controller to ^1.18.5; lockfile updates.

Written by Cursor Bugbot for commit f5ad9c1. This will update automatically on new commits. Configure here.


Important

Adds EnterInviteCodeSheet for sponsor invite codes, enhances GlassBottomSheet keyboard handling, refactors profile.tsx, updates LogSlipUpSheet, and expands tests.

  • New Component:
    • EnterInviteCodeSheet.tsx: Bottom sheet for entering sponsor invite codes with 8-character validation, auto-capitalization, and loading states.
  • Enhancements:
    • GlassBottomSheet.tsx: Adds keyboardBehavior and keyboardBlurBehavior props for improved keyboard handling.
  • Refactor:
    • profile.tsx: Replaces inline invite code input with EnterInviteCodeSheet for better keyboard UX on iOS.
  • Updates:
    • LogSlipUpSheet.tsx: Adopts new keyboard props and improves date picker handling.
  • Testing:
    • Adds 29 new tests for EnterInviteCodeSheet covering rendering, validation, submission, and dismissal.

This description was created by Ellipsis for f5ad9c1. You can customize this summary. It will automatically update as commits are pushed.

BillChirico and others added 14 commits December 9, 2025 14:57
Downgrades `react` from 19.2.1 to 19.1.0 and `@types/react` from 19.2.7 to 19.1.17 to maintain compatibility with other dependencies. Updates `expo-updates` from 29.0.14 to 29.0.15 for minor improvements.

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/react"
  dependency-version: 19.1.17
  dependency-type: direct:development
  update-type: version-update:semver-minor
- dependency-name: "expo-updates"
  dependency-version: 29.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...
Design document for comprehensive navigation overhaul:
- iOS 26 Liquid Glass aesthetic (tab bar, headers, sheets)
- react-native-bottom-tabs for native iOS/Android tab bars
- react-native-keyboard-controller for native keyboard handling
- @gorhom/bottom-sheet for all modals (Settings, Tasks, etc.)
- Web top navigation bar
- Airbnb strict code standards via eslint-config-airbnb-extended
…le.id

- Refactored the ProfileScreen component to utilize user.id for various operations, ensuring compliance with RLS policies.
- Updated conditions and database interactions to replace profile.id with user.id in invite code handling and notifications.
- Enhanced logic to check for user presence alongside profile, improving robustness of the invite code functionality.
Bumps [react-native-screens](https://github.com/software-mansion/react-native-screens) from 4.16.0 to 4.18.0.
- [Release notes](https://github.com/software-mansion/react-native-screens/releases)
- [Commits](software-mansion/react-native-screens@4.16.0...4.18.0)

---
updated-dependencies:
- dependency-name: react-native-screens
  dependency-version: 4.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@react-native-community/datetimepicker](https://github.com/react-native-datetimepicker/datetimepicker) from 8.4.4 to 8.5.1.
- [Release notes](https://github.com/react-native-datetimepicker/datetimepicker/releases)
- [Changelog](https://github.com/react-native-datetimepicker/datetimepicker/blob/master/CHANGELOG.md)
- [Commits](react-native-datetimepicker/datetimepicker@v8.4.4...v8.5.1)

---
updated-dependencies:
- dependency-name: "@react-native-community/datetimepicker"
  dependency-version: 8.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#127)

Bumps [@react-navigation/bottom-tabs](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/bottom-tabs) from 7.8.11 to 7.8.12.
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/[email protected]/packages/bottom-tabs/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/[email protected]/packages/bottom-tabs)

---
updated-dependencies:
- dependency-name: "@react-navigation/bottom-tabs"
  dependency-version: 7.8.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react-native-svg](https://github.com/react-native-community/react-native-svg) from 15.12.1 to 15.15.1.
- [Release notes](https://github.com/react-native-community/react-native-svg/releases)
- [Commits](software-mansion/react-native-svg@v15.12.1...v15.15.1)

---
updated-dependencies:
- dependency-name: react-native-svg
  dependency-version: 15.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together.

Updates `react` from 19.1.0 to 19.2.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.1/packages/react)

Updates `@types/react` from 19.1.17 to 19.2.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/react"
  dependency-version: 19.2.7
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…lows

- Added a new section for Test-Driven Development (TDD) outlining the required cycle and workflow.
- Included detailed guidelines on what requires tests and common anti-patterns to avoid in TDD.
- Expanded the verification checklist for UI changes, emphasizing the importance of visual verification.
- Documented Jest configuration and mock strategies for testing, along with performance testing guidelines.
- Updated the commit workflow to emphasize atomic commits and the use of Conventional Commits.
- Enhanced the documentation for advanced Expo configuration and Firebase integration.
- Added comprehensive notes on ESLint and Prettier configurations, including pre-commit hooks.
- Improved clarity and structure throughout the document for better developer experience.
…failures

- Introduced a new section detailing guidelines for pushing changes, including verification steps to ensure a clean working state.
- Added a list of scenarios when pushing should be avoided, such as failing tests or uncommitted changes.
- Documented procedures for handling push failures, including rebase conflict resolution and the importance of avoiding force pushes on main branches.
- Emphasized the critical nature of visual verification before committing UI changes.
Resolve conflicts:
- Remove AnimatedBottomNav.tsx (replaced by native liquid glass tabs in main)
- Regenerate pnpm-lock.yaml
- Create new EnterInviteCodeSheet component for sponsor invite code entry
- Use GlassBottomSheet with interactive keyboard behavior
- Add BottomSheetTextInput for proper keyboard handling in bottom sheets
- Refactor profile.tsx to use sheet-based invite code entry
- Add keyboard behavior props to GlassBottomSheet (keyboardBehavior, keyboardBlurBehavior)
- Update LogSlipUpSheet with same keyboard improvements
- Add comprehensive tests for EnterInviteCodeSheet
- Update profile tests to reflect sheet-based architecture
Copilot AI review requested due to automatic review settings December 11, 2025 06:13
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 11, 2025

Warning

Rate limit exceeded

@BillChirico has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 21 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8b0c7fb and f5ad9c1.

📒 Files selected for processing (4)
  • __tests__/app/profile.test.tsx (16 hunks)
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx (1 hunks)
  • __tests__/lib/validation.test.ts (1 hunks)
  • app/(tabs)/profile.tsx (16 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a new EnterInviteCodeSheet component with imperative present/dismiss API and validation, moves profile invite flow into the sheet and updates useAuth to include user, adds keyboardBlurBehavior support and Android back-button handling to GlassBottomSheet, swaps LogSlipUpSheet to BottomSheetTextInput, expands tests/mocks and documentation, and adjusts two dependencies.

Changes

Cohort / File(s) Summary
New Invite Code sheet & types
components/sheets/EnterInviteCodeSheet.tsx
New forwardRef bottom-sheet component exporting present()/dismiss() via EnterInviteCodeSheetRef; props include onSubmit(inviteCode: string): Promise<void>; enforces uppercase alphanumeric 8-char input, live count, loading/error handling, accessibility, theming, and form reset on dismiss.
Profile integration
app/(tabs)/profile.tsx
Replaces inline invite UI with EnterInviteCodeSheet usage via ref; joinWithInviteCode(inviteCode: string) accepts a code and throws errors for sheet-level handling; useAuth return extended to { user, profile, refreshProfile }; layout uses KeyboardAwareScrollView.
GlassBottomSheet prop & back handler
components/GlassBottomSheet.tsx
Adds optional prop `keyboardBlurBehavior?: 'none'
LogSlipUpSheet keyboard/input changes
components/sheets/LogSlipUpSheet.tsx
Replaces TextInput with BottomSheetTextInput, increases snap points to ['50%','90%'], changes keyboardBehavior to "interactive", and sets keyboardBlurBehavior="restore".
Tests: EnterInviteCodeSheet suite
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx
Adds comprehensive tests for rendering, ref API, sanitization, validation, submit flows, error handling, dismissal, reset behavior; uses mocks for bottom-sheet, icons, and theme.
Tests: profile & keyboard avoidance updates
__tests__/app/profile.test.tsx, __tests__/app/profile.keyboard-avoidance.test.tsx
Updates tests to use mocked EnterInviteCodeSheet (forwardRef stub); adds mocks for lucide-react-native X and @gorhom/bottom-sheet BottomSheetTextInput; profile tests now assert sheet trigger and basic interactions.
Tests: GlassBottomSheet back handler & jest setup
__tests__/components/GlassBottomSheet.test.tsx, jest.setup.js, __tests__/*
Adds BackHandler mock utilities in jest.setup.js and test helpers for registering/removing/simulating back presses; platform-conditional tests verify listener registration/removal and dismissal; introduces related mocks.
LogSlipUpSheet tests update
__tests__/components/sheets/LogSlipUpSheet.test.tsx
Adjusts test scaffolding to render BottomSheetTextInput mock and reflect updated keyboard behavior and snap points.
Documentation & process
CLAUDE.md
Large documentation expansion: adds pnpm test:ci, formal TDD workflow, verification checklist, Jest/mock guidance, CI/env notes (Daily Codebase Review), commit/push conventions, examples, and security/build notes.
Package changes
package.json
Removes expo-haptics; downgrades react-native-keyboard-controller from ^1.20.1 to ^1.18.5.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Profile as ProfileScreen
    participant Sheet as EnterInviteCodeSheet
    participant UI as GlassBottomSheet
    participant Auth as useAuth / joinWithInviteCode
    participant API as Backend/API

    User->>Profile: tap "Enter Invite Code"
    Profile->>Sheet: inviteCodeSheetRef.present()
    Sheet->>UI: render GlassBottomSheet (keyboardBehavior/keyboardBlurBehavior)
    User->>Sheet: enter code & submit
    Sheet->>Auth: onSubmit -> joinWithInviteCode(code)
    Auth->>API: verify / join invite
    API-->>Auth: success / error
    alt success
        Auth-->>Sheet: resolve
        Sheet->>Sheet: dismiss(), reset state
        Sheet->>Profile: optionally refreshProfile / notify
    else error
        Auth-->>Sheet: throw error
        Sheet->>User: display specific or generic error
    end
Loading

Suggested labels

authentication, refactor, testing, dependencies, supabase, ios, android, documentation

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(profile): add EnterInviteCodeSheet with keyboard handling' accurately summarizes the main changes: a new sheet component for invite code entry with keyboard improvements, refactoring of profile to use it.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description clearly relates to the changeset, detailing the new EnterInviteCodeSheet component, GlassBottomSheet enhancements, profile.tsx refactor, and comprehensive test coverage.

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.

❤️ Share

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

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Dec 11, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new bottom sheet component for entering sponsor invite codes with improved keyboard handling, replacing the previous inline input approach. The changes enhance the user experience on iOS by providing proper keyboard interaction and a more polished UI flow.

Key changes:

  • New EnterInviteCodeSheet component with comprehensive input validation and loading states
  • Enhanced GlassBottomSheet with configurable keyboard behavior props
  • Refactored profile screen to use sheet-based invite code entry instead of inline input

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
package.json Downgraded react-native-keyboard-controller to v1.18.5
components/sheets/LogSlipUpSheet.tsx Updated to use BottomSheetTextInput and adjusted keyboard behavior settings
components/sheets/EnterInviteCodeSheet.tsx New component for invite code entry with validation and keyboard handling
components/GlassBottomSheet.tsx Added keyboardBlurBehavior prop for iOS keyboard dismissal behavior
app/(tabs)/profile.tsx Refactored to use EnterInviteCodeSheet instead of inline input
__tests__/components/sheets/LogSlipUpSheet.test.tsx Added mock for BottomSheetTextInput
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx New comprehensive test suite with 29 tests
__tests__/app/profile.test.tsx Updated tests to reflect sheet-based invite code entry
__tests__/app/profile.keyboard-avoidance.test.tsx Updated keyboard avoidance tests for sheet-based approach
CLAUDE.md Added extensive TDD workflow documentation and testing guidelines
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/(tabs)/profile.tsx Outdated
@claude claude Bot added feature New feature frontend Frontend/UI related changes testing Testing related changes labels Dec 11, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 11, 2025

Codecov Report

❌ Patch coverage is 65.18519% with 47 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.57%. Comparing base (22080a4) to head (f5ad9c1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
app/(tabs)/profile.tsx 36.23% 44 Missing ⚠️
components/sheets/LogSlipUpSheet.tsx 0.00% 2 Missing ⚠️
components/sheets/EnterInviteCodeSheet.tsx 98.18% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #132      +/-   ##
==========================================
+ Coverage   81.43%   81.57%   +0.14%     
==========================================
  Files          52       53       +1     
  Lines        3776     3789      +13     
  Branches     1373     1369       -4     
==========================================
+ Hits         3075     3091      +16     
+ Misses        679      676       -3     
  Partials       22       22              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread CLAUDE.md Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
__tests__/app/profile.test.tsx (1)

1358-1427: Nice added coverage for invite generation errors, sponsee stats, and relationship failures

The new blocks around “Generate Invite Code Error”, “sponsee task statistics”, and relationship fetch/disconnect error handling add valuable coverage for previously fragile paths (DB insert failures, aggregate task stats, and thrown errors from supabase.from). Tests assert that the UI remains stable and appropriate alerts/derived values are shown.

Given how often supabase.from.mockImplementation patterns are repeated across describes and test files, consider extracting small helpers (e.g., mockRelationshipsQuery, mockTaskStatsQuery, mockInviteInsertError) into a shared test module to reduce duplication and keep the setup logic consistent.

Also applies to: 1429-1529, 1531-1559, 1593-1683

app/(tabs)/profile.tsx (1)

1055-1096: Remove unused style definitions.

These styles (inviteInputContainer, inviteInput, inviteSubmitButton, inviteSubmitText, inviteCancelButton, inviteCancelText) were used by the old inline invite code input UI that has been replaced by EnterInviteCodeSheet. They are now dead code.

     actionButtonText: {
       fontSize: 16,
       fontFamily: theme.fontRegular,
       fontWeight: '600',
       color: theme.text,
       marginLeft: 12,
     },
-    inviteInputContainer: {
-      backgroundColor: theme.card,
-      padding: 16,
-      borderRadius: 12,
-      shadowColor: theme.black,
-      shadowOffset: { width: 0, height: 2 },
-      shadowOpacity: 0.1,
-      shadowRadius: 8,
-      elevation: 3,
-    },
-    inviteInput: {
-      backgroundColor: theme.borderLight,
-      borderRadius: 8,
-      padding: 12,
-      fontSize: 16,
-      fontFamily: theme.fontRegular,
-      marginBottom: 12,
-      color: theme.text,
-    },
-    inviteSubmitButton: {
-      backgroundColor: theme.primary,
-      borderRadius: 8,
-      padding: 12,
-      alignItems: 'center',
-      marginBottom: 8,
-    },
-    inviteSubmitText: {
-      fontSize: 16,
-      fontFamily: theme.fontRegular,
-      fontWeight: '600',
-      color: theme.white,
-    },
-    inviteCancelButton: {
-      padding: 12,
-      alignItems: 'center',
-    },
-    inviteCancelText: {
-      fontSize: 16,
-      fontFamily: theme.fontRegular,
-      fontWeight: '600',
-      color: theme.textSecondary,
-    },
     loadingContainer: {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22080a4 and 07ab2d2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • CLAUDE.md (9 hunks)
  • __tests__/app/profile.keyboard-avoidance.test.tsx (4 hunks)
  • __tests__/app/profile.test.tsx (13 hunks)
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx (1 hunks)
  • __tests__/components/sheets/LogSlipUpSheet.test.tsx (1 hunks)
  • app/(tabs)/profile.tsx (12 hunks)
  • components/GlassBottomSheet.tsx (3 hunks)
  • components/sheets/EnterInviteCodeSheet.tsx (1 hunks)
  • components/sheets/LogSlipUpSheet.tsx (3 hunks)
  • package.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: All database operations must use typed client from types/database.ts (source of truth)
Use ErrorBoundary component for graceful failure handling
All imports must use @/ path alias (configured in tsconfig.json)
File organization order: imports → types → constants → helpers → main logic → exports with required section comments
JSDoc/TSDoc documentation is mandatory for all exported functions and components
Use mount status tracking with useRef to prevent closure issues in async operations

**/*.{ts,tsx}: Run pnpm typecheck to verify TypeScript types before committing
Write tests for any new or modified code, including happy path, edge cases, and error handling
Every exported function, hook, and component MUST have JSDoc/TSDoc comments that work with IntelliSense
Prefer interface for defining object shapes in TypeScript
Use strict mode in TypeScript (strict: true in tsconfig); avoid any type, use unknown with type guards instead
Use database types from types/database.ts as the source of truth
Use Supabase client with typed database schema (types/database.ts); all data models derive from database types
Use platform-aware storage: SecureStore (native) / localStorage (web)
Session tokens are stored securely (SecureStore on native, localStorage on web)
Tasks flow unidirectionally from sponsor → sponsee within a relationship

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/GlassBottomSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: NEVER use console.log/error/warn directly - use logger from lib/logger.ts
All logs are automatically sent to Sentry as breadcrumbs with categorized metadata using LogCategory enum
Logger reserved keys (error_message, error_stack, error_name) must be avoided in metadata
Boolean variables must use is/has/should prefix (isLoading, hasSlipUps)

**/*.{ts,tsx,js,jsx}: Run pnpm lint to check for code quality issues using ESLint before committing
Use camelCase for function and variable names
Use PascalCase for component and type/interface names
Use SCREAMING_SNAKE_CASE for constants
Use 'is', 'has', or 'should' prefix for boolean variables (e.g., isLoading, hasSlipUps)
Use 'handle' prefix for event handlers (e.g., handlePress, handleSubmit)
Name async functions with verbs describing the action (e.g., fetchTasks, updateProfile)
Always use @/ path alias for all local imports
Remove unused imports before committing
Always pass Error objects to logger.error() for stack traces and include contextual metadata
Validate and sanitize all user inputs
Use universal logger (lib/logger.ts) for centralized, structured logging with categorization via LogCategory enum
Five log levels available: logger.error(), logger.warn(), logger.info(), logger.debug(), logger.trace()
Organize files logically with sections: imports, types, constants, helper functions, component, styles

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/GlassBottomSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx}: Use renderWithProviders from test-utils to wrap components with AuthContext/ThemeContext in tests
Test mocks must include platform detection (defaults to iOS) and timezone handling

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
**/*.{ts,tsx,js,jsx,json,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Run pnpm format to ensure consistent code formatting before committing

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/GlassBottomSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • package.json
  • components/sheets/LogSlipUpSheet.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
**/__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/__tests__/**/*.test.{ts,tsx}: Run pnpm test to verify all tests pass and coverage stays above 80% before committing
Place test files in __tests__/ directory mirroring the source structure (e.g., app/(tabs)/profile.tsx__tests__/app/profile.test.tsx)
Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
All tests must use descriptive test names and be independent; group related tests with describe() blocks
Clean up mocks in beforeEach() or afterEach() blocks in tests
Test behavior, not implementation details
Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Use MSW (Mock Service Worker) for API mocking in tests
Add regression tests for bug fixes that would have caught the bug
Update tests when modifying existing code; add new tests for new behavior
Use renderWithProviders helper function to wrap test components with required contexts
Mock navigation with expo-router mocks in tests

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/GlassBottomSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • package.json
  • components/sheets/LogSlipUpSheet.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/components/**/*.{ts,tsx}: Use functional components with hooks (no class components) in React/React Native
Use StyleSheet.create() for component styles instead of inline style objects
Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles

Files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/GlassBottomSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
🧠 Learnings (60)
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Test behavior, not implementation details

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Add regression tests for bug fixes that would have caught the bug

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tests/**/*.{ts,tsx} : Add comprehensive test coverage for components, hooks, utilities, and API routes in tests/ directory

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to jest.setup.ts : Initialize testing-library/jest-dom and mocks in jest.setup.ts for unit test setup

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use `renderWithProviders` helper function to wrap test components with required contexts

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use MSW (Mock Service Worker) for API mocking in tests

Applied to files:

  • __tests__/components/sheets/LogSlipUpSheet.test.tsx
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native

Applied to files:

  • components/sheets/EnterInviteCodeSheet.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling

Applied to files:

  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : All tests must use descriptive test names and be independent; group related tests with `describe()` blocks

Applied to files:

  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing

Applied to files:

  • __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx} : Run pnpm test to ensure all unit tests pass after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Use `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` validation workflow before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Run complete validation workflow: `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: After changing any files, run validation workflow: `pnpm format && pnpm typecheck && pnpm lint && pnpm test && pnpm build`. All checks must pass before committing.

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Run pnpm lint to check for code quality issues including type-aware linting after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to tests/**/*.{ts,tsx,js} : Use Jest for unit tests located in `tests/` directory

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css} : Run pnpm build to verify production build passes after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css,json,md} : Run pnpm format to ensure consistent code formatting after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run `pnpm lint` to check for code quality issues using ESLint before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to verify TypeScript types before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,css} : Run `pnpm format` to ensure consistent code formatting before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT skip validation checks to save time - all validation checks must pass before changes are considered complete

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : Supabase client must be mocked with chainable query builder in jest.setup.js

Applied to files:

  • CLAUDE.md
  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to {jest.config.ts,jest.setup.ts,tests/**/*.{ts,tsx}} : Use Jest with Testing Library for unit tests located in tests/ directory with configuration via jest.config.ts and setup via jest.setup.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests

Applied to files:

  • CLAUDE.md
  • __tests__/app/profile.test.tsx
  • __tests__/app/profile.keyboard-avoidance.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests

Applied to files:

  • CLAUDE.md
  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use Supabase client with typed database schema (`types/database.ts`); all data models derive from database types

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to .env* : Use `EXPO_PUBLIC_*` prefix for environment variables available in client-side code; other vars are build-time only

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript mode with explicit types for public APIs

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use database types from `types/database.ts` as the source of truth

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tsconfig.json : Enable strict TypeScript mode in project configuration

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use 'handle' prefix for event handlers (e.g., `handlePress`, `handleSubmit`)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : All database operations must use typed client from `types/database.ts` (source of truth)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Name async functions with verbs describing the action (e.g., `fetchTasks`, `updateProfile`)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use PascalCase for component and type/interface names

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects

Applied to files:

  • CLAUDE.md
  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Organize files logically with sections: imports, types, constants, helper functions, component, styles

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/hooks/**/*.{ts,tsx} : Extract reusable logic into custom hooks

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : File organization order: imports → types → constants → helpers → main logic → exports with required section comments

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Conventional Branch naming format: `<type>/<description>` (e.g., feat/user-authentication, fix/login-validation-error)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Tasks flow unidirectionally from sponsor → sponsee within a relationship

Applied to files:

  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/app/page.tsx : Use Promise.allSettled in src/app/page.tsx to tolerate partial content loading failures and log issues via reportError

Applied to files:

  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to src/app/page.tsx : Homepage must use `Promise.allSettled()` for data fetching to tolerate partial content loading failures

Applied to files:

  • __tests__/app/profile.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Authentication flow in root layout must route users: unauthenticated → /login, authenticated without profile → /onboarding, fully onboarded → /(tabs)

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Context API for global state (AuthContext, ThemeContext) wrapping the entire app in `app/_layout.tsx`; do not use Redux/Zustand

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to {app/_layout.tsx,**/*context*.{ts,tsx}} : Use Context API only (no Redux/Zustand) - contexts must wrap entire app in root layout

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use framer-motion for motion and animation effects in navigation, hero, products, about, mentorship, and blog section components

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Routing uses Expo Router v6 with typed routes (file-based routing in `app/`) and authentication flow enforced in root layout (`app/_layout.tsx`)

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to app/_layout.tsx : Root layout (`app/_layout.tsx`) must enforce auth routing: no user → `/login`, user without profile → `/onboarding`, complete profile → `/(tabs)`

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to contexts/AuthContext.tsx : AuthContext must provide: `user`, `session`, `profile`, `loading`, and auth methods

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*auth*context*.{ts,tsx} : AuthContext must provide: user, session, profile, loading, auth methods

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Invite codes must connect sponsors to sponsees without requiring email exchange

Applied to files:

  • app/(tabs)/profile.tsx
🧬 Code graph analysis (5)
__tests__/components/sheets/LogSlipUpSheet.test.tsx (1)
jest.setup.js (11)
  • React (3-3)
  • React (176-176)
  • React (241-241)
  • React (365-365)
  • React (376-376)
  • React (405-405)
  • React (413-413)
  • React (427-427)
  • React (435-435)
  • ScrollView (10-10)
  • TextInput (7-7)
components/sheets/EnterInviteCodeSheet.tsx (2)
contexts/ThemeContext.tsx (1)
  • ThemeColors (8-36)
components/GlassBottomSheet.tsx (1)
  • GlassBottomSheetRef (48-65)
__tests__/components/sheets/EnterInviteCodeSheet.test.tsx (3)
jest.setup.js (2)
  • ScrollView (10-10)
  • TextInput (7-7)
components/sheets/EnterInviteCodeSheet.tsx (1)
  • EnterInviteCodeSheetRef (36-46)
components/ErrorBoundary.tsx (1)
  • render (48-54)
__tests__/app/profile.test.tsx (2)
app/(tabs)/profile.tsx (1)
  • ProfileScreen (166-882)
lib/supabase.ts (1)
  • supabase (78-87)
__tests__/app/profile.keyboard-avoidance.test.tsx (1)
app/(tabs)/profile.tsx (1)
  • ProfileScreen (166-882)
🪛 LanguageTool
CLAUDE.md

[uncategorized] ~741-~741: The official name of this software platform is spelled with a capital “H”.
Context: ... or edit 4. Daily Codebase Review (.github/workflows/daily-codebase-review.yml): ...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md

402-402: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Unit Tests
  • GitHub Check: Build for Web
  • GitHub Check: auto-label
  • GitHub Check: Cursor Bugbot
  • GitHub Check: claude-review
🔇 Additional comments (24)
package.json (1)

76-76: Confirm intentional downgrade of react-native-keyboard-controller

The version change to "react-native-keyboard-controller": "^1.18.5" looks deliberate to align with the new keyboard behavior pattern, but it’s a downgrade from the previously noted version. Please double‑check that 1.18.5 is the intended target and is fully compatible with React Native 0.81.5 and your current keyboard handling usage.

components/sheets/LogSlipUpSheet.tsx (1)

21-21: Bottom sheet keyboard handling and text input integration look solid

Using BottomSheetScrollView/BottomSheetTextInput plus keyboardBehavior="interactive" and keyboardBlurBehavior="restore" with the expanded ['50%', '90%'] snap points is consistent with Gorhom’s expected patterns and should improve iOS keyboard UX while keeping behavior explicit. Notes wiring (value/onChangeText, placeholder, multiline, alignment) mirrors the prior TextInput usage.

Also applies to: 298-302, 383-392

components/GlassBottomSheet.tsx (1)

105-117: New keyboardBlurBehavior prop is cleanly wired and backwards‑compatible

Exposing keyboardBlurBehavior?: 'none' | 'restore' with a default of 'none' preserves existing behavior while giving sheets (e.g., invite/slip‑up flows) fine‑grained control over iOS keyboard dismissal. Forwarding it directly to BottomSheetModal keeps the wrapper thin and consistent.

Please just confirm your @gorhom/bottom-sheet version indeed supports the keyboardBlurBehavior prop as typed here.

Also applies to: 153-162, 281-281

__tests__/app/profile.keyboard-avoidance.test.tsx (1)

186-205: Keyboard-avoidance tests correctly isolate sheet behavior behind mocks

Extending the lucide and @gorhom/bottom-sheet mocks (including BottomSheetTextInput) plus mocking EnterInviteCodeSheet lets this file focus purely on ProfileScreen’s keyboard/structure concerns. The “Enter Invite Code” test now verifies the button is present and pressable, while detailed sheet behavior is covered in EnterInviteCodeSheet.test.tsx, which keeps responsibilities nicely separated.

Also applies to: 335-362, 440-449

__tests__/app/profile.test.tsx (1)

325-352: Profile tests now correctly delegate invite code behavior to EnterInviteCodeSheet

Updating the lucide and Gorhom mocks and introducing a mock EnterInviteCodeSheet while narrowing the Profile tests to “button exists and is clickable” is a good split of concerns: ProfileScreen verifies wiring (button, sheet presence), and the detailed validation/submission flows live in EnterInviteCodeSheet.test.tsx. The inline comments documenting this delegation make the intent clear for future readers.

Also applies to: 506-527, 599-608, 677-687, 848-848, 1333-1354

components/sheets/EnterInviteCodeSheet.tsx (7)

1-16: LGTM!

Imports are well-organized using the @/ path alias as required. All necessary React hooks, React Native components, and external dependencies are properly imported.


22-71: LGTM!

Well-documented interfaces with proper JSDoc examples. The ref API follows the established pattern from GlassBottomSheetRef, and props are appropriately typed with optional onClose callback.


104-122: LGTM!

Correctly implements mount status tracking with useRef to prevent state updates after unmount, following the coding guidelines for async operations. State variables use appropriate is prefix for boolean (isSubmitting).


127-133: LGTM!

The imperative API correctly resets form state before presenting, ensuring a clean slate each time the sheet opens.


167-197: LGTM!

The handleSubmit function correctly:

  • Guards against double submission with isSubmitting check
  • Validates input length before proceeding
  • Uses mount guards in async code paths
  • Handles errors gracefully with user-friendly fallback message

306-410: LGTM!

Styles are properly created using StyleSheet.create() as per coding guidelines, with comprehensive theme integration and good organization.


293-294: LGTM!

Good practice setting displayName for better debugging experience in React DevTools.

app/(tabs)/profile.tsx (12)

36-38: LGTM!

Import of EnterInviteCodeSheet and its ref type follows the @/ path alias convention.


174-174: LGTM!

The ref is correctly typed with EnterInviteCodeSheetRef and follows the established pattern for other sheet refs in this component.


315-327: LGTM on JSDoc and function signature refactor.

Good documentation for the refactored function. The parameter-based approach allows the sheet to handle input while the profile screen handles the business logic.


366-368: Correct use of user.id for self-connection check.

Using user.id (auth UID) instead of profile.id ensures the check aligns with the RLS policy constraints where sponsee_id = auth.uid().


400-411: Correct RLS alignment for invite_codes.used_by.

The comment on lines 400-401 correctly documents that the RLS WITH CHECK clause requires used_by = auth.uid(). Using user.id satisfies this constraint.


438-446: Error re-throw pattern enables sheet error display.

The catch block correctly re-throws errors (preserving the original message if available) so the EnterInviteCodeSheet can display them to users. This is cleaner than the previous alert-based approach.


614-619: LGTM!

Simple handler following the handle prefix naming convention with appropriate JSDoc documentation.


624-634: LGTM!

KeyboardAwareScrollView provides better keyboard handling for the profile screen, with appropriate configuration for tap handling and scroll indicators.


757-772: LGTM!

The UI correctly provides invite code entry via the sheet for both new users (no sponsor) and existing users (additional sponsor). This replaces the previous inline input approach for better keyboard UX.


12-14: The ScrollView import is still needed. It's used as a type annotation for the scrollViewRef on line 175 (const scrollViewRef = useRef<ScrollView>(null)), so the import should be retained.

Likely an incorrect or invalid review comment.


167-167: useAuth hook correctly returns the user property.

The AuthContextType interface defines user: User | null, and the useAuth hook properly retrieves it from AuthContext. This aligns with RLS policy compliance where sponsee_id = auth.uid() is matched against the user's auth ID.


382-398: RLS policy correctly enforced for sponsee_id.

The code correctly uses user.id for sponsee_id, which satisfies the RLS policy constraint sponsee_id = auth.uid(). This ensures users can only create relationships for themselves, maintaining critical security alignment. The comment documenting this requirement is accurate and necessary.

Comment thread __tests__/components/sheets/EnterInviteCodeSheet.test.tsx
Comment thread __tests__/components/sheets/LogSlipUpSheet.test.tsx
Comment thread app/(tabs)/profile.tsx Outdated
Comment thread CLAUDE.md Outdated
Comment thread components/sheets/EnterInviteCodeSheet.tsx
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Signed-off-by: Bill Chirico <[email protected]>
Copilot AI review requested due to automatic review settings December 11, 2025 06:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread components/sheets/LogSlipUpSheet.tsx
Comment thread app/(tabs)/profile.tsx
Comment thread app/(tabs)/profile.tsx
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 11, 2025

Note

Docstrings generation - SKIPPED

All docstrings were kept as they were. No new docstrings were generated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07ab2d2 and 038c47b.

📒 Files selected for processing (1)
  • CLAUDE.md (9 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)

Files:

  • CLAUDE.md
🧠 Learnings (43)
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: After changing any files, run validation workflow: `pnpm format && pnpm typecheck && pnpm lint && pnpm test && pnpm build`. All checks must pass before committing.

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx} : Run pnpm test to ensure all unit tests pass after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT commit or push changes - allow the user to do this manually

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Do NOT skip validation checks to save time; all checks must pass before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Use `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` validation workflow before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Run complete validation workflow: `pnpm format && pnpm lint && pnpm typecheck && pnpm build:web && pnpm test` before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Run pnpm lint to check for code quality issues including type-aware linting after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to tests/**/*.{ts,tsx,js} : Use Jest for unit tests located in `tests/` directory

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css} : Run pnpm build to verify production build passes after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx,css,json,md} : Run pnpm format to ensure consistent code formatting after any file changes

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run `pnpm lint` to check for code quality issues using ESLint before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to verify TypeScript types before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,css} : Run `pnpm format` to ensure consistent code formatting before committing

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Do NOT skip validation checks to save time - all validation checks must pass before changes are considered complete

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : Supabase client must be mocked with chainable query builder in jest.setup.js

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to {jest.config.ts,jest.setup.ts,tests/**/*.{ts,tsx}} : Use Jest with Testing Library for unit tests located in tests/ directory with configuration via jest.config.ts and setup via jest.setup.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use Supabase client with typed database schema (`types/database.ts`); all data models derive from database types

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to .env* : Use `EXPO_PUBLIC_*` prefix for environment variables available in client-side code; other vars are build-time only

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:08:12.192Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T00:08:12.192Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript mode with explicit types for public APIs

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use database types from `types/database.ts` as the source of truth

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tsconfig.json : Enable strict TypeScript mode in project configuration

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use 'handle' prefix for event handlers (e.g., `handlePress`, `handleSubmit`)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : All database operations must use typed client from `types/database.ts` (source of truth)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Name async functions with verbs describing the action (e.g., `fetchTasks`, `updateProfile`)

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use PascalCase for component and type/interface names

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Organize files logically with sections: imports, types, constants, helper functions, component, styles

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/hooks/**/*.{ts,tsx} : Extract reusable logic into custom hooks

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : File organization order: imports → types → constants → helpers → main logic → exports with required section comments

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Conventional Branch naming format: `<type>/<description>` (e.g., feat/user-authentication, fix/login-validation-error)

Applied to files:

  • CLAUDE.md
🪛 LanguageTool
CLAUDE.md

[uncategorized] ~741-~741: The official name of this software platform is spelled with a capital “H”.
Context: ... or edit 4. Daily Codebase Review (.github/workflows/daily-codebase-review.yml): ...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md

402-402: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (7)
CLAUDE.md (7)

32-32: Approve: CI test command documentation

The addition of pnpm test:ci appropriately documents the CI testing mode and complements the existing testing command documentation.


71-123: Approve: Comprehensive TDD workflow documentation

The new TDD section effectively establishes RED/GREEN/REFACTOR expectations with clear workflow steps, practical examples, and an anti-patterns table. This strengthens the testing culture documented in the project guidelines and aligns with the PR's emphasis on test-driven development.


137-161: Approve: Commit workflow documentation

The new atomic commit workflow with Conventional Commits examples is clear and practical. Using immediate commits for each completed task followed by a single push is sound guidance for multi-task sessions.


163-200: Approve: Pushing guidelines and force-push warning

The pushing guidelines are thorough, including a strong warning against force-pushing to main/develop, proper rebase guidance, and clear decision criteria for when to push. This provides necessary safeguards for collaborative development.


201-262: Approve: Visual verification and API testing guidance

The expanded visual verification section with Chrome DevTools MCP workflows, comprehensive checklists, and network/API verification guidance provides solid guardrails for catching runtime issues before committing. The practical examples and severity classifications enhance developer confidence.


264-399: Approve: Error handling, performance, and form validation guidance

The console error severity table, performance testing workflow, and extensive form validation edge cases (email, password, text, date fields) demonstrate thorough QA mindset. The authentication flows section appropriately addresses the app's auth-guarded routes.


1005-1069: Approve: TypeScript, ESLint, and Prettier configuration documentation

The expanded TypeScript configuration section, ESLint setup with clear no-console exceptions, Prettier settings table, and pre-commit hooks documentation provide developers with comprehensive guidance. The branch naming and commit message conventions are well-detailed with practical examples.

Comment thread CLAUDE.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +104 to +105
const EnterInviteCodeSheet = forwardRef<EnterInviteCodeSheetRef, EnterInviteCodeSheetProps>(
({ theme, onSubmit, onClose }, ref) => {
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The component documentation states that onClose is optional with @optional, but the parameter is not marked as optional in the actual interface definition (line 70). The documentation and implementation should align - either mark the parameter as onClose?: () => void in the props interface or remove the @optional tag from the JSDoc.

Copilot uses AI. Check for mistakes.
Comment thread jest.setup.js Outdated
Comment on lines +164 to +168
// Mock document for web platform tests (keyboard event handling)
global.document = {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
};
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The document mock only includes addEventListener and removeEventListener, but web environments may require additional document properties or methods. Consider using a more complete mock object or using jsdom for web-specific tests to avoid potential issues with code that accesses other document properties.

Copilot uses AI. Check for mistakes.
Comment thread app/(tabs)/profile.tsx Outdated
Comment on lines +895 to +897
onClose={() => {
// Sheet dismissed without submitting
}}
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The onClose callback is an empty function with only a comment. If no action is needed on close, consider either removing this prop (since it's optional) or implementing meaningful cleanup logic. Empty callbacks with only comments suggest incomplete implementation.

Suggested change
onClose={() => {
// Sheet dismissed without submitting
}}

Copilot uses AI. Check for mistakes.
Extend the minimal document mock with commonly used properties and
methods to prevent errors when code accesses document APIs beyond
addEventListener/removeEventListener.

Includes mocks for:
- DOM queries (getElementById, querySelector, etc.)
- Element creation (createElement, createTextNode)
- Document properties (body, head, documentElement)
- Document state (readyState, visibilityState, hidden)
…eSheet

The onClose prop is optional and no cleanup is needed when the sheet
is dismissed without submitting, so remove the empty callback.
Copilot AI review requested due to automatic review settings December 11, 2025 07:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread components/sheets/LogSlipUpSheet.tsx Outdated
Comment on lines 371 to 380
// On Android with display="default", the native dialog auto-closes
// on OK/Cancel press. We must hide the picker component to prevent
// it from reopening. On iOS, display="default" also shows a dialog.
//
// IMPORTANT: Update the date BEFORE hiding the picker to ensure
// the state update completes before the component unmounts.
if (date) {
setSlipUpDate(date);
}
setShowDatePicker(false);
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The comment mentions that the date update order is important to prevent state updates after unmount, but the logic always calls setShowDatePicker(false) regardless of whether date is defined. Consider clarifying that the unconditional call is intentional because the native dialog auto-closes on both OK and Cancel, and the order only matters when date is defined (OK pressed).

Copilot uses AI. Check for mistakes.
…deSheet

The mounted state tracking pattern is an anti-pattern in React 18+.
React's automatic batching handles cleanup appropriately when components
unmount during async operations, making manual mount tracking unnecessary.
Removed misleading reference to unmount timing. The comment now accurately
describes that the native dialog auto-closes on OK/Cancel and we always
hide the picker to sync React state with the native UI.
Copilot AI review requested due to automatic review settings December 11, 2025 07:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 7 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json
Comment on lines 54 to 57
"expo-device": "^8.0.10",
"expo-font": "~14.0.10",
"expo-glass-effect": "~0.1.8",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The removal of expo-haptics at line 57 is not documented in the PR description or commit message. If haptics are no longer needed, ensure that all references to expo-haptics in the codebase have been removed to avoid runtime errors.

Copilot uses AI. Check for mistakes.
Comment on lines +373 to 377
// When date is defined (OK pressed), update it before hiding.
if (date) {
setSlipUpDate(date);
}
setShowDatePicker(false);
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The order of operations has been reversed from the original code. Previously, setShowDatePicker(false) was called first, then the date was conditionally updated. Now the date is updated before hiding the picker. This change means the picker UI will show the updated date briefly before closing, which could cause a visual flash. The original order was correct for avoiding this flash.

Suggested change
// When date is defined (OK pressed), update it before hiding.
if (date) {
setSlipUpDate(date);
}
setShowDatePicker(false);
// Hide the picker first to avoid a visual flash, then update the date if needed.
setShowDatePicker(false);
if (date) {
setSlipUpDate(date);
}

Copilot uses AI. Check for mistakes.
Comment thread components/sheets/EnterInviteCodeSheet.tsx Outdated
Comment thread app/(tabs)/profile.tsx Outdated
Comment on lines +855 to +871
{/* Android: Use native date picker dialog (has its own OK/Cancel buttons) */}
{Platform.OS === 'android' && showSobrietyDatePicker && (
<DateTimePicker
value={selectedSobrietyDate}
mode="date"
display="default"
onChange={(event, date) => {
// Always hide picker on Android since dialog auto-closes
setShowSobrietyDatePicker(false);
// Only update if user pressed OK (date is defined)
if (date) {
updateSobrietyDate(date);
}
}}
maximumDate={maximumDate}
/>
)}
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The Android date picker logic differs from the iOS implementation in the modal above (lines 819-853). The iOS version uses a separate 'Done' button, while Android updates immediately on selection. This inconsistency may confuse users switching platforms. Consider documenting this platform difference or unifying the behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +278 to +290
it('shows generic error when onSubmit throws non-Error', async () => {
mockOnSubmit.mockRejectedValueOnce('Something went wrong');
renderSheet();

const input = screen.getByPlaceholderText('Enter 8-character code');
fireEvent.changeText(input, 'ABC12345');

fireEvent.press(screen.getByTestId('connect-button'));

await waitFor(() => {
expect(screen.getByText('Failed to connect. Please try again.')).toBeTruthy();
});
});
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

This test verifies error handling for non-Error rejections, but the actual component code at line 179 uses err instanceof Error ? err.message : 'Failed to connect. Please try again.'. The test should also verify that the isSubmitting state is properly reset after an error, as this affects the UI state.

Copilot uses AI. Check for mistakes.
});
});
});
// Note: Invite Code Validation and Invalid tests are now covered in EnterInviteCodeSheet.test.tsx
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

Multiple test sections have been removed and replaced with notes pointing to EnterInviteCodeSheet.test.tsx. However, the integration between the profile screen and the sheet (e.g., the joinWithInviteCode callback) is not tested in the new sheet tests. Consider adding integration tests that verify the profile screen properly calls the sheet and handles its callbacks.

Copilot uses AI. Check for mistakes.
Comment thread CLAUDE.md
pnpm test # Run all Jest tests
pnpm test:watch # Run tests in watch mode
pnpm test -- --coverage # Run tests with coverage report (80% minimum required)
pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions)
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The pnpm test:ci command is documented here but does not appear in the package.json scripts. This documentation is misleading as the command will not work. Either add the script to package.json or remove this line from the documentation.

Suggested change
pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions)

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Bill Chirico <[email protected]>
Copilot AI review requested due to automatic review settings December 11, 2025 07:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// Extend global for TypeScript
declare global {
var __backHandlerListeners: (() => boolean)[] | undefined;
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

Using var in a TypeScript global declaration is unconventional. While this works for global declarations, consider using const or let for consistency with modern JavaScript practices, or explicitly document why var is required for global scope hoisting.

Suggested change
var __backHandlerListeners: (() => boolean)[] | undefined;
let __backHandlerListeners: (() => boolean)[] | undefined;

Copilot uses AI. Check for mistakes.
Comment thread jest.setup.js Outdated
BillChirico and others added 2 commits December 11, 2025 02:42
Clarify why iOS and Android date pickers have different UX:
- iOS: Spinner picker needs explicit "Update" button (no clear confirmation point)
- Android: Native dialog has OK/Cancel, confirming immediately matches platform conventions

This intentional difference follows each platform's design guidelines.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Bill Chirico <[email protected]>
Copilot AI review requested due to automatic review settings December 11, 2025 07:46
- Add functional mock for EnterInviteCodeSheet that captures onSubmit prop
- Add integration tests verifying profile passes joinWithInviteCode to sheet
- Add tests for sheet button presentation on Enter Invite Code click
- Add tests for joinWithInviteCode success flow with Alert verification
- Add tests for all error cases (invalid, expired, used, self-connect, duplicate, profile fetch fail, relationship creation fail)
- Add onSubmit callback tests in EnterInviteCodeSheet test suite
- Test async onSubmit resolution and rejection handling
- Test retry after failure behavior
- Test code capitalization before submission
…deSheet

Both error handling tests now verify that the submit button becomes
enabled again after an error, ensuring proper UI state recovery.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

package.json:1

  • The removal of expo-haptics package should be accompanied by verification that no code references this dependency. Search the codebase for any imports or usage of expo-haptics to ensure this removal is safe.
{

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const sanitized = text.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
setInviteCode(sanitized);
setError(null);
}, []);
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The handleChangeText function has an empty dependency array but calls setInviteCode and setError. While this works because setState functions are stable, it's better practice to include them in the dependency array for clarity and to avoid potential issues if the implementation changes.

Suggested change
}, []);
}, [setInviteCode, setError]);

Copilot uses AI. Check for mistakes.
value={inviteCode}
onChangeText={handleChangeText}
placeholder="Enter 8-character code"
placeholderTextColor={theme.textTertiary}
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The autoCapitalize="characters" prop is redundant since handleChangeText already forces uppercase via .toUpperCase(). The input sanitization in handleChangeText takes precedence, so this prop has no effect. Consider removing it or documenting that it serves as a hint for mobile keyboards even though the value is enforced programmatically.

Suggested change
placeholderTextColor={theme.textTertiary}
placeholderTextColor={theme.textTertiary}
// Hint for mobile keyboards to show uppercase, actual value is enforced via handleChangeText

Copilot uses AI. Check for mistakes.
Comment on lines +191 to +200
// Only add BackHandler listener on Android platform when sheet is open
if (Platform.OS !== 'android' || !isOpen) return;

const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
// Dismiss the sheet and return true to indicate event was handled
bottomSheetRef.current?.dismiss();
return true;
});

return () => subscription.remove();
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The early return condition !isOpen means the effect cleanup function is never executed when the sheet closes, since the effect doesn't run when isOpen is false. This is correct behavior, but the cleanup in line 200 (return () => subscription.remove()) will only run when the component unmounts or when dependencies change while isOpen is true. Consider documenting this behavior or restructuring to make the lifecycle clearer.

Suggested change
// Only add BackHandler listener on Android platform when sheet is open
if (Platform.OS !== 'android' || !isOpen) return;
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
// Dismiss the sheet and return true to indicate event was handled
bottomSheetRef.current?.dismiss();
return true;
});
return () => subscription.remove();
// Only add BackHandler listener on Android platform
if (Platform.OS !== 'android') return;
let subscription: { remove: () => void } | null = null;
if (isOpen) {
subscription = BackHandler.addEventListener('hardwareBackPress', () => {
// Dismiss the sheet and return true to indicate event was handled
bottomSheetRef.current?.dismiss();
return true;
});
}
return () => {
if (subscription) {
subscription.remove();
}
};

Copilot uses AI. Check for mistakes.
Comment thread app/(tabs)/profile.tsx
@@ -163,17 +164,15 @@ function SponsorDaysDisplay({
* @returns A React element representing the profile screen
*/
export default function ProfileScreen() {
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The addition of user destructuring from useAuth() is used throughout the refactored invite code flow. However, there's inconsistency in the codebase: some operations use profile.id while others now use user.id. This is correct per RLS policies (as documented in comments), but it may be confusing. Consider adding a comment at the destructuring site explaining when to use user.id vs profile.id.

Suggested change
export default function ProfileScreen() {
export default function ProfileScreen() {
// NOTE: Both `user` and `profile` are destructured from useAuth().
// Use `user.id` for authentication/authorization (RLS policies), and `profile.id` for profile-related data.
// See RLS documentation/comments for details. Be careful to use the correct ID in each context.

Copilot uses AI. Check for mistakes.
Comment thread app/(tabs)/profile.tsx
Comment on lines +818 to +821
{/* iOS: Custom modal with spinner picker requires explicit "Update" button
because the spinner UI allows continuous scrolling without clear confirmation.
This matches iOS platform conventions for date selection. */}
{Platform.OS === 'ios' && showSobrietyDatePicker && (
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The platform-specific date picker implementations (iOS modal with Update button vs Android native dialog) are well-commented, but they duplicate logic for handling date selection. Consider extracting the date update logic into a shared handler to reduce duplication between lines 838 and 868.

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +184
it('sanitizes input to alphanumeric only', () => {
renderSheet();
const input = screen.getByPlaceholderText('Enter 8-character code');

fireEvent.changeText(input, 'ABC-123!@#');

expect(input.props.value).toBe('ABC123');
});
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The test verifies that special characters are stripped, but it doesn't test what happens when the input contains only special characters (e.g., '!!!!'). Consider adding a test case for this edge case to ensure the component handles it gracefully.

Copilot uses AI. Check for mistakes.
Comment thread CLAUDE.md
pnpm test # Run all Jest tests
pnpm test:watch # Run tests in watch mode
pnpm test -- --coverage # Run tests with coverage report (80% minimum required)
pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions)
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The new pnpm test:ci command is documented but it's unclear if this command actually exists in package.json. Verify that the command is defined in the scripts section of package.json, or update this documentation if it's a planned addition.

Suggested change
pnpm test:ci # Run tests with coverage in CI mode (used by GitHub Actions)
pnpm test:ci # (Planned addition) Will run tests with coverage in CI mode (used by GitHub Actions)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
components/sheets/LogSlipUpSheet.tsx (2)

298-298: Verify UX on smaller devices with increased sheet height.

The snap point increased from 70% to 90%, which significantly expands the sheet's coverage. Ensure this doesn't negatively impact visibility and usability on smaller devices like iPhone SE.


371-377: Verify date picker update order doesn't cause visual flash.

The updated logic now sets slipUpDate before hiding the picker, which reverses the previous order. A past review comment (lines 373-377) noted that hiding the picker first avoids a visual flash when the updated date briefly renders before the picker closes.

The new comment states the order only matters when date is defined, but the visual flash concern may still apply. Please verify this change was intentional and test on physical devices to ensure no UI flickering occurs.

app/(tabs)/profile.tsx (1)

366-367: Consider clarifying redundant ID checks.

The condition checks both user.id and profile.id for self-sponsorship prevention. Since these should always match (user.id from auth, profile.id from database), consider either:

  1. Documenting why both checks are needed (if there's an edge case where they differ)
  2. Simplifying to user.id only if they're guaranteed identical

The current defensive approach is safe but may be unnecessarily cautious.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb5241e and 8b0c7fb.

📒 Files selected for processing (5)
  • __tests__/components/GlassBottomSheet.test.tsx (4 hunks)
  • app/(tabs)/profile.tsx (14 hunks)
  • components/sheets/EnterInviteCodeSheet.tsx (1 hunks)
  • components/sheets/LogSlipUpSheet.tsx (4 hunks)
  • jest.setup.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: All database operations must use typed client from types/database.ts (source of truth)
Use ErrorBoundary component for graceful failure handling
All imports must use @/ path alias (configured in tsconfig.json)
File organization order: imports → types → constants → helpers → main logic → exports with required section comments
JSDoc/TSDoc documentation is mandatory for all exported functions and components
Use mount status tracking with useRef to prevent closure issues in async operations

**/*.{ts,tsx}: Run pnpm typecheck to verify TypeScript types before committing
Write tests for any new or modified code, including happy path, edge cases, and error handling
Every exported function, hook, and component MUST have JSDoc/TSDoc comments that work with IntelliSense
Prefer interface for defining object shapes in TypeScript
Use strict mode in TypeScript (strict: true in tsconfig); avoid any type, use unknown with type guards instead
Use database types from types/database.ts as the source of truth
Use Supabase client with typed database schema (types/database.ts); all data models derive from database types
Use platform-aware storage: SecureStore (native) / localStorage (web)
Session tokens are stored securely (SecureStore on native, localStorage on web)
Tasks flow unidirectionally from sponsor → sponsee within a relationship

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • app/(tabs)/profile.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: NEVER use console.log/error/warn directly - use logger from lib/logger.ts
All logs are automatically sent to Sentry as breadcrumbs with categorized metadata using LogCategory enum
Logger reserved keys (error_message, error_stack, error_name) must be avoided in metadata
Boolean variables must use is/has/should prefix (isLoading, hasSlipUps)

**/*.{ts,tsx,js,jsx}: Run pnpm lint to check for code quality issues using ESLint before committing
Use camelCase for function and variable names
Use PascalCase for component and type/interface names
Use SCREAMING_SNAKE_CASE for constants
Use 'is', 'has', or 'should' prefix for boolean variables (e.g., isLoading, hasSlipUps)
Use 'handle' prefix for event handlers (e.g., handlePress, handleSubmit)
Name async functions with verbs describing the action (e.g., fetchTasks, updateProfile)
Always use @/ path alias for all local imports
Remove unused imports before committing
Always pass Error objects to logger.error() for stack traces and include contextual metadata
Validate and sanitize all user inputs
Use universal logger (lib/logger.ts) for centralized, structured logging with categorization via LogCategory enum
Five log levels available: logger.error(), logger.warn(), logger.info(), logger.debug(), logger.trace()
Organize files logically with sections: imports, types, constants, helper functions, component, styles

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • jest.setup.js
  • app/(tabs)/profile.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx}: Use renderWithProviders from test-utils to wrap components with AuthContext/ThemeContext in tests
Test mocks must include platform detection (defaults to iOS) and timezone handling

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
**/*.{ts,tsx,js,jsx,json,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Run pnpm format to ensure consistent code formatting before committing

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • jest.setup.js
  • app/(tabs)/profile.tsx
**/__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/__tests__/**/*.test.{ts,tsx}: Run pnpm test to verify all tests pass and coverage stays above 80% before committing
Place test files in __tests__/ directory mirroring the source structure (e.g., app/(tabs)/profile.tsx__tests__/app/profile.test.tsx)
Use Jest with React Native Testing Library for testing; mock Supabase client for database operations
All tests must use descriptive test names and be independent; group related tests with describe() blocks
Clean up mocks in beforeEach() or afterEach() blocks in tests
Test behavior, not implementation details
Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations
Use MSW (Mock Service Worker) for API mocking in tests
Add regression tests for bug fixes that would have caught the bug
Update tests when modifying existing code; add new tests for new behavior
Use renderWithProviders helper function to wrap test components with required contexts
Mock navigation with expo-router mocks in tests

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
!(lib/logger.ts|lib/sentry.ts|jest.setup.js)

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint no-console rule; never use console.log/error/warn directly - use the universal logger instead (exceptions: logger.ts, sentry.ts, jest.setup.js)

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • jest.setup.js
  • app/(tabs)/profile.tsx
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/components/**/*.{ts,tsx}: Use functional components with hooks (no class components) in React/React Native
Use StyleSheet.create() for component styles instead of inline style objects
Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles

Files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
{lib/logger.ts,lib/sentry.ts,jest.setup.js}

📄 CodeRabbit inference engine (AGENTS.md)

Console.log/error/warn are only permitted in logger.ts, sentry.ts, and jest.setup.js

Files:

  • jest.setup.js
jest.setup.js

📄 CodeRabbit inference engine (AGENTS.md)

jest.setup.js: Supabase client must be mocked with chainable query builder in jest.setup.js
AsyncStorage and SecureStore must be mocked to prevent actual storage during tests

Files:

  • jest.setup.js
🧠 Learnings (34)
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Test mocks must include platform detection (defaults to iOS) and timezone handling

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Test behavior, not implementation details

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to tests/**/*.{ts,tsx} : Add comprehensive test coverage for components, hooks, utilities, and API routes in tests/ directory

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Update tests when modifying existing code; add new tests for new behavior

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Add regression tests for bug fixes that would have caught the bug

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Clean up mocks in `beforeEach()` or `afterEach()` blocks in tests

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Wrap test components with AuthContext, ThemeContext; mock Supabase client for database operations

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Mock navigation with expo-router mocks in tests

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use Jest with React Native Testing Library for testing; mock Supabase client for database operations

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use MSW (Mock Service Worker) for API mocking in tests

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Run `pnpm test` to verify all tests pass and coverage stays above 80% before committing

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Write tests for any new or modified code, including happy path, edge cases, and error handling

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : All tests must use descriptive test names and be independent; group related tests with `describe()` blocks

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode in TypeScript (`strict: true` in tsconfig); avoid `any` type, use `unknown` with type guards instead

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/__tests__/**/*.test.{ts,tsx} : Use `renderWithProviders` helper function to wrap test components with required contexts

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.test.{ts,tsx} : Use `renderWithProviders` from test-utils to wrap components with AuthContext/ThemeContext in tests

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Define Props interfaces inline or export if shared; use StyleSheet.create() for component styles

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to jest.setup.ts : Initialize testing-library/jest-dom and mocks in jest.setup.ts for unit test setup

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to jest.setup.js : AsyncStorage and SecureStore must be mocked to prevent actual storage during tests

Applied to files:

  • __tests__/components/GlassBottomSheet.test.tsx
  • jest.setup.js
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use functional components with hooks (no class components) in React/React Native

Applied to files:

  • components/sheets/LogSlipUpSheet.tsx
  • components/sheets/EnterInviteCodeSheet.tsx
  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : Use mount status tracking with useRef to prevent closure issues in async operations

Applied to files:

  • components/sheets/EnterInviteCodeSheet.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*.{ts,tsx} : JSDoc/TSDoc documentation is mandatory for all exported functions and components

Applied to files:

  • components/sheets/EnterInviteCodeSheet.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Authentication flow in root layout must route users: unauthenticated → /login, authenticated without profile → /onboarding, fully onboarded → /(tabs)

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Invite codes must connect sponsors to sponsees without requiring email exchange

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: No role field in database `profiles` table; role is contextual based on relationship (sponsor_id vs sponsee_id)

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to app/_layout.tsx : Root layout (`app/_layout.tsx`) must enforce auth routing: no user → `/login`, user without profile → `/onboarding`, complete profile → `/(tabs)`

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Supabase RLS policies for data access control

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Use Context API for global state (AuthContext, ThemeContext) wrapping the entire app in `app/_layout.tsx`; do not use Redux/Zustand

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to {app/_layout.tsx,**/*context*.{ts,tsx}} : Use Context API only (no Redux/Zustand) - contexts must wrap entire app in root layout

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T00:07:55.345Z
Learnt from: CR
Repo: VolvoxCommunity/Volvox.Website PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T00:07:55.345Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use framer-motion for motion and animation effects in navigation, hero, products, about, mentorship, and blog section components

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to **/components/**/*.{ts,tsx} : Use StyleSheet.create() for component styles instead of inline style objects

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to app/_layout.tsx : Routing uses Expo Router v6 with typed routes (file-based routing in `app/`) and authentication flow enforced in root layout (`app/_layout.tsx`)

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-04T03:11:15.142Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-04T03:11:15.142Z
Learning: Applies to contexts/AuthContext.tsx : AuthContext must provide: `user`, `session`, `profile`, `loading`, and auth methods

Applied to files:

  • app/(tabs)/profile.tsx
📚 Learning: 2025-12-02T03:55:42.734Z
Learnt from: CR
Repo: VolvoxCommunity/Sobriety-Waypoint PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T03:55:42.734Z
Learning: Applies to **/*auth*context*.{ts,tsx} : AuthContext must provide: user, session, profile, loading, auth methods

Applied to files:

  • app/(tabs)/profile.tsx
🧬 Code graph analysis (3)
__tests__/components/GlassBottomSheet.test.tsx (2)
components/GlassBottomSheet.tsx (1)
  • GlassBottomSheetRef (48-65)
__tests__/test-utils.tsx (1)
  • renderWithProviders (59-64)
components/sheets/EnterInviteCodeSheet.tsx (2)
contexts/ThemeContext.tsx (1)
  • ThemeColors (8-36)
components/GlassBottomSheet.tsx (1)
  • GlassBottomSheetRef (48-65)
app/(tabs)/profile.tsx (5)
contexts/AuthContext.tsx (1)
  • useAuth (50-56)
contexts/ThemeContext.tsx (1)
  • useTheme (112-118)
hooks/useTabBarPadding.ts (1)
  • useTabBarPadding (58-69)
components/SettingsSheet.tsx (1)
  • SettingsSheetRef (75-85)
components/sheets/EnterInviteCodeSheet.tsx (1)
  • EnterInviteCodeSheetRef (29-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build for Web
  • GitHub Check: Unit Tests
  • GitHub Check: claude-review
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (19)
components/sheets/LogSlipUpSheet.tsx (3)

21-21: LGTM! Correct component for bottom sheet context.

The switch to BottomSheetTextInput ensures proper keyboard integration with the bottom sheet modal.


300-301: Enhanced keyboard behavior improves UX.

The change to keyboardBehavior="interactive" enables smoother keyboard-driven scrolling, and keyboardBlurBehavior="restore" ensures the sheet returns to its original position when the keyboard dismisses. These align with the PR's keyboard handling improvements.


388-398: LGTM! Consistent bottom sheet text input usage.

The switch to BottomSheetTextInput for the notes field maintains consistency with bottom sheet best practices and ensures proper keyboard behavior.

__tests__/components/GlassBottomSheet.test.tsx (4)

10-13: Global declaration correctly uses var.

The var keyword is appropriate here for TypeScript global augmentation. Unlike regular code where let/const are preferred, global declarations require var for proper hoisting and scope. The past comment suggesting let would not work for this use case.


95-128: Well-structured BackHandler test utilities.

The helper functions provide a clean abstraction over the global mock with proper LIFO ordering that matches Android's real BackHandler behavior. The JSDoc documentation clearly explains each function's purpose.


142-143: Proper test cleanup prevents state leakage.

Clearing BackHandler listeners in afterEach follows testing best practices and prevents state pollution between test cases.

Based on learnings, test cleanup in afterEach blocks is a coding guideline requirement.


382-487: Comprehensive Android back button test coverage.

This test suite thoroughly covers:

  • Listener registration on sheet presentation
  • Back button dismissal behavior
  • Listener cleanup on dismissal
  • Platform-specific behavior (Android vs iOS/web)

The tests properly use act() for imperative actions and follow React Testing Library best practices by testing behavior rather than implementation details.

Based on learnings, tests should be behavior-focused and use descriptive names with proper cleanup.

jest.setup.js (2)

131-154: BackHandler mock enables Android behavior testing.

The mock correctly:

  • Stores listeners in global.__backHandlerListeners for test access
  • Returns a remover object with remove() matching React Native's API
  • Allows tests to simulate hardware back button presses

This integrates seamlessly with the test utilities added to GlassBottomSheet.test.tsx.


164-212: Comprehensive document mock for web compatibility.

The manual document mock provides essential DOM APIs (event handling, queries, element creation) for tests without requiring jsdom. The comment correctly explains why jsdom isn't used (Jest's node environment configuration), which addresses the past review concern about conflicting guidance.

components/sheets/EnterInviteCodeSheet.tsx (5)

1-96: Well-structured component with comprehensive documentation.

The component follows coding guidelines:

  • Proper file organization (imports → types → component)
  • JSDoc documentation for all exported interfaces
  • Props interface properly defines onClose as optional (line 63)

Based on learnings, JSDoc/TSDoc documentation is mandatory for all exported functions and components.


102-108: Ref-based submission tracking correctly implements onClose contract.

The didSubmitSuccessfullyRef successfully addresses the past comment about the onClose contract violation. By tracking successful submissions, the component ensures onClose is only called when dismissed without submitting, as documented.


150-155: Correct useCallback dependencies for state setters.

The empty dependency array is correct. React guarantees that setInviteCode and setError have stable identities and don't need to be included in the dependency array. This is idiomatic React and won't cause stale closures.


157-183: Robust submission handling with proper guards and error handling.

The implementation correctly:

  • Prevents double submissions with guard check
  • Validates input before submission
  • Tracks successful submission for proper onClose behavior
  • Provides user-friendly error messages
  • Resets loading state in finally block

The absence of unmount guards is correct for React 18+, where AbortController or automatic cleanup is preferred over manual isMountedRef patterns.


231-244: Accessible text input with proper test hooks.

The input field correctly implements:

  • testID="invite-code-input" for testing (addresses past review comment)
  • accessibilityLabel for screen readers
  • Character validation with auto-capitalization
  • No autoFocus (avoiding accessibility concerns from past comments)
app/(tabs)/profile.tsx (5)

14-14: LGTM! Proper integration of new keyboard and sheet components.

The additions correctly:

  • Import KeyboardAwareScrollView for enhanced keyboard handling
  • Import EnterInviteCodeSheet and its ref type
  • Access user from useAuth for RLS policy compliance
  • Declare inviteCodeSheetRef for imperative sheet control

All imports use the @/ path alias per coding guidelines.

Also applies to: 36-38, 167-167, 174-174


315-447: Well-refactored invite code handler with improved error flow.

The refactored function correctly:

  • Accepts inviteCode as a parameter for sheet-based flow
  • Throws errors for the sheet to display (lines 443-445)
  • Uses user.id for RLS policy compliance (lines 382, 401, 404, 419, 422)
  • Validates invite code thoroughly before creating relationship

The error handling pattern aligns well with the EnterInviteCodeSheet's error display mechanism.


624-634: Enhanced keyboard handling with KeyboardAwareScrollView.

The switch to KeyboardAwareScrollView from react-native-keyboard-controller provides:

  • Smooth keyboard-aware scrolling
  • Proper tap handling with keyboardShouldPersistTaps="handled"
  • Integration with the new sheet-based flows

This aligns with the PR's objective to improve keyboard behavior across the app.


857-873: Platform-appropriate date picker patterns with clear documentation.

The comments effectively explain the platform differences:

  • iOS: Custom modal with spinner requires explicit "Update" button (lines 818-820)
  • Android: Native dialog with built-in OK/Cancel provides immediate confirmation (lines 857-859)

This documentation addresses the past review concern about platform inconsistency and follows each platform's conventions.


892-898: Properly conditional sheet rendering prevents unnecessary mounting.

The sheet is only rendered when both profile and user exist, which:

  • Prevents mounting before authentication/profile is loaded
  • Matches the pattern used for LogSlipUpSheet (lines 879-889)
  • Addresses the past review comment requesting conditional rendering

The onSubmit callback correctly wires to the refactored joinWithInviteCode function.

Comment thread app/(tabs)/profile.tsx
throw new Error('You are already connected to this sponsor');
}

// Use user.id for sponsee_id to satisfy RLS policy: sponsee_id = auth.uid()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider consolidating redundant RLS policy comments.

Lines 382 and 401 both explain the same RLS constraint requiring auth.uid(). Consider consolidating these into a single, more detailed comment that could reference the specific RLS policy or migration file, or have the second comment reference the first.

Example for line 401:

-      // Use user.id (auth.uid()) instead of profile.id to satisfy RLS policy
-      // The WITH CHECK clause requires: used_by = auth.uid()
+      // Use user.id to satisfy RLS policy (see comment on line 382)

Also applies to: 401-401

🤖 Prompt for AI Agents
In app/(tabs)/profile.tsx around lines 382 and 401 there are duplicate comments
explaining the same RLS constraint (sponsee_id = auth.uid()); consolidate them
by keeping a single, slightly more detailed comment (e.g., at the first
occurrence) that references the exact RLS policy name or migration file and
remove the redundant second comment or replace it with a short pointer like "see
comment above (line 382)" so the codebase has one authoritative explanation.

- Add handleSobrietyDateConfirm callback to reduce duplication between iOS and Android date pickers
- Wrap updateSobrietyDate in useCallback for stable dependency
- Both iOS modal buttons and Android native dialog now use the same handler
- Handler accepts undefined to cancel, or Date to confirm and update
Add test to verify validateDisplayName correctly rejects input
containing only special characters (e.g., '!!!!', '@#$%', '****').
Copilot AI review requested due to automatic review settings December 11, 2025 07:55
@BillChirico BillChirico merged commit 8052ef0 into main Dec 11, 2025
8 of 12 checks passed
@BillChirico BillChirico deleted the develop branch December 11, 2025 07:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

package.json:1

  • The package expo-haptics has been removed, but there's no mention in the PR description about why this dependency was removed or if haptic feedback functionality was used elsewhere in the codebase. If this package was in use, ensure haptic feedback calls have been removed or replaced.
{

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread jest.setup.js
Comment on lines +164 to +167
// Mock document for web platform tests (keyboard event handling, DOM access, etc.)
// This provides a more complete mock to avoid errors when code accesses document properties.
// Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available.
// This manual mock provides basic document functionality for compatibility in tests.
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The comment states 'Jest is configured to use the node environment (see CLAUDE.md)' but the reason for mocking document in a Node environment is unclear. If this mock is for web platform code paths, consider clarifying which components or code paths require DOM access in tests despite using the Node environment.

Suggested change
// Mock document for web platform tests (keyboard event handling, DOM access, etc.)
// This provides a more complete mock to avoid errors when code accesses document properties.
// Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available.
// This manual mock provides basic document functionality for compatibility in tests.
// Mock document for web platform code paths that require DOM access in tests.
// Specifically, this mock is needed for:
// - Keyboard event handling logic in src/platform/web/KeyboardManager.js
// - Web-specific code in src/platform/web/ and tests in __tests__/web/
// Note: Jest is configured to use the 'node' environment (see CLAUDE.md), so jsdom is not available.
// This manual mock provides basic document functionality for compatibility in these tests.

Copilot uses AI. Check for mistakes.
Comment on lines +195 to +201
// Dismiss the sheet and return true to indicate event was handled
bottomSheetRef.current?.dismiss();
return true;
});

return () => subscription.remove();
}, [isOpen]);
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The BackHandler listener always returns true, preventing any parent components from handling the back press. Consider if there are scenarios where the sheet should not consume the back press (e.g., if enablePanDownToClose is false, or if there's unsaved form data that needs confirmation).

Suggested change
// Dismiss the sheet and return true to indicate event was handled
bottomSheetRef.current?.dismiss();
return true;
});
return () => subscription.remove();
}, [isOpen]);
// Only handle back press if sheet is dismissible
if (enablePanDownToClose) {
bottomSheetRef.current?.dismiss();
return true;
}
// Allow event to propagate if not dismissible
return false;
});
return () => subscription.remove();
}, [isOpen, enablePanDownToClose]);

Copilot uses AI. Check for mistakes.
Comment thread app/(tabs)/profile.tsx
Comment on lines +644 to +654
<KeyboardAwareScrollView
ref={scrollViewRef}
style={[styles.keyboardAvoidingContainer, { backgroundColor: theme.background }]}
contentContainerStyle={{
paddingBottom: scrollPadding,
flexGrow: 1,
backgroundColor: theme.background,
}}
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={true}
>
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The backgroundColor: theme.background is duplicated in both style and contentContainerStyle. This is likely unnecessary—the background color on style should be sufficient. Consider removing the duplicate to simplify the code.

Copilot uses AI. Check for mistakes.
Comment on lines +173 to +183
it('rejects input containing only special characters', () => {
expect(validateDisplayName('!!!!')).toBe(
'Display name can only contain letters, spaces, periods, and hyphens'
);
expect(validateDisplayName('@#$%')).toBe(
'Display name can only contain letters, spaces, periods, and hyphens'
);
expect(validateDisplayName('****')).toBe(
'Display name can only contain letters, spaces, periods, and hyphens'
);
});
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The test validates that special characters are rejected, but the expected error message mentions 'letters, spaces, periods, and hyphens'. Ensure this matches the actual validation logic in the validateDisplayName function. If the function allows additional characters (like numbers), update the test's expected message accordingly.

Copilot uses AI. Check for mistakes.
Comment thread app/(tabs)/profile.tsx
onChange={(event, date) => handleSobrietyDateConfirm(date)}
maximumDate={maximumDate}
/>
)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Android DateTimePicker may update date on dismiss

The Android DateTimePicker's onChange handler passes the date directly to handleSobrietyDateConfirm on line 882. On Android, when the user presses "Cancel" in the date picker dialog, onChange is still called but date may be the currently selected date (not undefined) depending on the DateTimePicker version. The current logic only checks if (date) which could cause the date to be updated even when the user cancels. This differs from the iOS behavior which only calls updateSobrietyDate when the user explicitly presses the "Update" button.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature frontend Frontend/UI related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants