Skip to content

feat(reset-password): setup ui & integrate logic#118

Merged
Cysteine12 merged 5 commits intodevelopfrom
feature/setup-reset-password-ui
Feb 27, 2026
Merged

feat(reset-password): setup ui & integrate logic#118
Cysteine12 merged 5 commits intodevelopfrom
feature/setup-reset-password-ui

Conversation

@Cysteine12
Copy link
Owner

@Cysteine12 Cysteine12 commented Feb 26, 2026

📌 Summary

  • adds a Reset Password screen with email, otp and new password set

🎯 Why is this change needed?

Closes #78


🧠 What was changed?

  • add the screen and a reset confirmation modal.

🏗️ Type of Change

  • Feature
  • Bug fix
  • Refactor
  • Performance improvement
  • Security fix
  • Documentation update
  • Test improvement
  • Breaking change

🧪 How was this tested?

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing
  • Postman tested
  • Not tested (explain why)

Test details:

  • Screen was tested manually with Expo go

📸 Screenshots / API Samples (if applicable)

Screenshot_20260227_020906_Expo Go.png

Summary by CodeRabbit

  • New Features

    • Added a dedicated Reset Password screen and flow with bottom-sheet success confirmation.
    • Introduced a reusable bottom-sheet and a press-scale interaction for tappable controls.
    • Added a confirmation modal after email verification.
  • Usability

    • Login now auto-focuses the password field after email entry.
    • Forgot Password button label changed to "Request Code".
  • Style

    • Increased button font weight across auth screens.
    • Added a gold icon color for consistent icon styling.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4a1a36 and 2acce2d.

📒 Files selected for processing (4)
  • mobile/components/reusables/ui/scale-pressable.tsx
  • mobile/features/auth/hook.ts
  • mobile/screens/auth/reset-password.tsx
  • mobile/screens/auth/verify-email.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • mobile/components/reusables/ui/scale-pressable.tsx
  • mobile/features/auth/hook.ts

📝 Walkthrough

Walkthrough

Adds a ResetPassword screen and route, a BottomSheet UI, a useResetPassword hook, input focus and button styling tweaks, SF→Material icon mappings with className support, a ScalePressable component and Button swap, and a new Colors.goldIcon constant.

Changes

Cohort / File(s) Summary
Navigation / Auth layout
mobile/app/(auth)/_layout.tsx, mobile/app/(auth)/reset-password.tsx
Registered reset-password route in auth stack and replaced the stub render with the real ResetPassword component.
Reset Password flow
mobile/screens/auth/reset-password.tsx, mobile/features/auth/hook.ts
Added full ResetPassword screen (reads email param, OTP + new password form, resetPassword mutation, success BottomSheet, auto-login/navigation) and new useResetPassword hook.
Auth screens & behavior tweaks
mobile/screens/auth/forgot-password.tsx, mobile/screens/auth/login.tsx, mobile/screens/auth/register.tsx, mobile/screens/auth/verify-email.tsx
Text/label and styling tweaks; login gains password field focus handling and returnKey behavior; verify-email adds BottomSheet modal flow on success.
UI primitives
mobile/components/ui/bottom-sheet.tsx, mobile/components/ui/icon-symbol.tsx
New BottomSheet component; IconSymbol adds two SF→Material mappings and accepts/forwards optional className.
Pressable animation
mobile/components/reusables/ui/scale-pressable.tsx, mobile/components/reusables/ui/button.tsx
Added ScalePressable animated wrapper and switched Button to render it instead of Pressable.
Theme constants
mobile/constants/theme.ts
Added exported color goldIcon.
Misc / Manifest
package.json
Manifest touched (minor).

Sequence Diagram

sequenceDiagram
    actor User
    participant App as "Mobile App (UI)"
    participant ResetScreen as "ResetPassword Screen"
    participant AuthAPI as "Auth API"
    participant BottomSheet as "BottomSheet Modal"
    participant LoginFlow as "Login Flow"

    User->>App: Open reset-password (with email param)
    App->>ResetScreen: render ResetPassword (email param)
    User->>ResetScreen: Enter OTP + new password
    ResetScreen->>AuthAPI: resetPassword({ email, otp, password })
    AuthAPI-->>ResetScreen: success
    ResetScreen->>BottomSheet: open(success)
    User->>BottomSheet: tap Continue
    BottomSheet->>LoginFlow: attempt auto-login (email+password) / navigate to Login
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇
I bounced a sheet and fixed a route,
OTPs now hop and boots reboot,
A golden glow on icons bright,
Press and scale—inputs take flight,
Hooray—passwords back in sight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: setting up a reset password UI and integrating the associated logic, which aligns with the core feature added in this PR.
Description check ✅ Passed The PR description follows the template structure with all required sections completed: summary, closing issue reference, technical changes, feature type selection, and manual testing verification with screenshots.
Linked Issues check ✅ Passed The PR fully implements the linked issue #78 objective: builds a reset password screen accepting email parameter with OTP and new password form inputs, includes success confirmation modal, and integrates the reset password logic.
Out of Scope Changes check ✅ Passed All changes are scoped to the reset password feature: new screen component, bottom sheet modal, icon mappings for UI, form hooks, and supporting UI component improvements (ScalePressable, button styling) are all necessary for the feature implementation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/setup-reset-password-ui

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the application's authentication flow by introducing a dedicated screen and backend integration for password resets. It provides users with a secure way to regain access to their accounts by verifying their identity via email and a one-time password, followed by setting a new password. The changes also include a new reusable UI component to improve user interaction for transient messages.

Highlights

  • Reset Password Feature Implementation: Implemented the complete client-side UI and integration logic for the 'Reset Password' functionality, allowing users to reset their password using an email and OTP.
  • New BottomSheet UI Component: Introduced a new reusable BottomSheet component to display modal content from the bottom of the screen, utilized for the password reset success confirmation.
  • Authentication Hook and Schema Updates: Extended the authentication hooks and schemas to include useResetPassword and ResetPasswordSchema, integrating the new password reset API.
Changelog
  • mobile/app/(auth)/_layout.tsx
    • Added the 'reset-password' screen to the authentication navigation stack.
  • mobile/app/(auth)/reset-password.tsx
    • Refactored the ResetPasswordScreen to import and render the ResetPassword component from the screens/auth directory.
  • mobile/components/ui/bottom-sheet.tsx
    • Added a new BottomSheet component, providing a modal overlay that slides up from the bottom of the screen.
  • mobile/components/ui/icon-symbol.tsx
    • Added new icon mappings for 'checkmark.circle' and 'arrow.forward'.
    • Introduced a className prop to the IconSymbol component for enhanced styling flexibility.
  • mobile/features/auth/hook.ts
    • Imported resetPassword API and ResetPasswordSchema for the new functionality.
    • Added a useResetPassword hook to handle the password reset mutation, including success and error handling.
  • mobile/screens/auth/forgot-password.tsx
    • Updated the button text from 'Continue' to 'Request Code' for clarity in the forgot password flow.
  • mobile/screens/auth/login.tsx
    • Added useRef for the password input field to enable programmatic focus.
    • Configured the email input's onSubmitEditing to automatically focus the password input for improved user experience.
  • mobile/screens/auth/reset-password.tsx
    • Added the ResetPassword screen component, including UI for password and OTP input fields.
    • Implemented form handling using useForm and integrated the useResetPassword hook.
    • Included a success confirmation modal using the new BottomSheet component, which redirects to login upon completion.
Activity
  • No specific activity (comments, reviews, or progress updates) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Cysteine12 Cysteine12 added enhancement New feature or request mobile Changes involving the mobile application labels Feb 26, 2026
@Cysteine12 Cysteine12 self-assigned this Feb 26, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the UI and logic for the password reset flow. A new reset-password screen is added, along with a BottomSheet component for modals. The changes are well-structured. My feedback includes suggestions to improve UI/UX consistency, maintainability by using theme-based styling, and fixing a minor form navigation issue.

Copy link
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: 3

Caution

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

⚠️ Outside diff range comments (1)
mobile/features/auth/hook.ts (1)

1-157: ⚠️ Potential issue | 🟡 Minor

Prettier warning is currently blocking CI.

Please run formatting on this file before merge to clear the pipeline warning.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/features/auth/hook.ts` around lines 1 - 157, Prettier formatting
errors are blocking CI; run your project's formatter (Prettier) on this file and
commit the changes so the file matches the repo's style. Specifically, format
mobile/features/auth/hook.ts (affects imports and spacing around functions like
useRegister, useLogin, useVerifyEmail, useRequestOtp, useForgotPassword,
useResetPassword, useLogout) by running the configured script (e.g., npm/yarn
format or npx prettier --write) and ensure the resulting file is staged and
pushed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mobile/components/ui/bottom-sheet.tsx`:
- Around line 24-33: The sheet container View in bottom-sheet.tsx lacks a
backgroundColor, causing transparency and poor readability; update the style
object inside the View (the one with
borderTopLeftRadius/borderTopRightRadius/paddingTop/paddingBottom/maxHeight/width)
to add a solid backgroundColor (e.g., use the existing
colors.containerBackground or theme background token) so the modal body is
opaque and readable across themes.

In `@mobile/screens/auth/reset-password.tsx`:
- Around line 1-147: The file fails CI due to Prettier formatting; run the
project's formatter (e.g., yarn prettier --write or npm run format) on this file
to fix style issues, then commit the formatted changes. Target the ResetPassword
component file (symbols: ResetPassword, useForm, useResetPassword, handleSubmit)
so the export default ResetPassword remains unchanged and no logic is
altered—only whitespace/formatting should be updated.
- Around line 56-59: The redirect call router.replace('/forgot-password') is
being invoked during render inside the reset-password component; move this
side-effect into a useEffect so it only runs after mount: inside the component,
replace the inline router.replace call with a state/flag (or simply check email
and in a useEffect(() => { if (!email) router.replace('/forgot-password') },
[email, router]) ) and return null (or a loading placeholder) from the render
while the redirect is pending; update any references to email and router
accordingly so no navigation happens during render.

---

Outside diff comments:
In `@mobile/features/auth/hook.ts`:
- Around line 1-157: Prettier formatting errors are blocking CI; run your
project's formatter (Prettier) on this file and commit the changes so the file
matches the repo's style. Specifically, format mobile/features/auth/hook.ts
(affects imports and spacing around functions like useRegister, useLogin,
useVerifyEmail, useRequestOtp, useForgotPassword, useResetPassword, useLogout)
by running the configured script (e.g., npm/yarn format or npx prettier --write)
and ensure the resulting file is staged and pushed.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0dfb10c and 8526ba0.

📒 Files selected for processing (8)
  • mobile/app/(auth)/_layout.tsx
  • mobile/app/(auth)/reset-password.tsx
  • mobile/components/ui/bottom-sheet.tsx
  • mobile/components/ui/icon-symbol.tsx
  • mobile/features/auth/hook.ts
  • mobile/screens/auth/forgot-password.tsx
  • mobile/screens/auth/login.tsx
  • mobile/screens/auth/reset-password.tsx

Comment on lines +1 to +147
import { Button } from '@/components/reusables/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/reusables/ui/card';
import { Input } from '@/components/reusables/ui/input';
import { Label } from '@/components/reusables/ui/label';
import BottomSheet from '@/components/ui/bottom-sheet';
import GoldGradient from '@/components/ui/gold-gradient';
import { IconSymbol } from '@/components/ui/icon-symbol';
import { useLogin, useResetPassword } from '@/features/auth/hook';
import { resetPasswordSchema, type ResetPasswordSchema } from '@/features/auth/schema';
import useForm from '@/hooks/use-app-form';
import { router, useLocalSearchParams } from 'expo-router';
import React, { useEffect, useRef, useState } from 'react';
import type { TextInput } from 'react-native';
import {
ActivityIndicator,
KeyboardAvoidingView,
Platform,
ScrollView,
Text,
useColorScheme,
View,
} from 'react-native';

const ResetPassword = () => {
const { mutate: login } = useLogin();
const colorScheme = useColorScheme();
const [isModalOpen, setModalOpen] = useState(false);
const { email } = useLocalSearchParams<{ email?: string }>();
const { mutate: resetPassword, isPending, data } = useResetPassword();
const { form, errors, handleChange, handleSubmit } = useForm<ResetPasswordSchema>({
data: {
email: email ?? '',
password: '',
otp: '',
},
schema: resetPasswordSchema,
onSubmit: (data) => resetPassword(data),
});

const otpRef = useRef<TextInput>(null);

useEffect(() => {
if (data?.success) {
setModalOpen(true);
}
}, [data]);

const handleCompleteModal = () => {
if (!form.email || !form.password) {
router.replace('/login');
return;
}
login({ email: form.email, password: form.password });
};

if (!email) {
router.replace('/forgot-password');
return;
}

return (
<KeyboardAvoidingView
className="flex-1"
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
keyboardVerticalOffset={Platform.OS === 'ios' ? 80 : 0}
>
<ScrollView
keyboardShouldPersistTaps="handled"
contentContainerClassName="sm:flex-1 items-center justify-center p-4 py-8 sm:py-4 sm:p-6 mt-safe"
keyboardDismissMode="interactive"
>
<View className="w-full max-w-sm">
<View className="gap-6">
<Card className="bg-transparent border-0">
<CardHeader>
<CardTitle className="text-center text-gold-text text-xl sm:text-left">Reset Your Password</CardTitle>
<CardDescription className="text-center sm:text-left">
Enter the One-Time Password sent to your email ({email}) and set your new account password
</CardDescription>
</CardHeader>
<CardContent className="gap-6">
<View className="gap-6">
<View className="gap-1.5">
<Label htmlFor="password">Password</Label>
<Input
id="password"
secureTextEntry
returnKeyType="send"
editable={!isPending}
value={form.password}
onChangeText={(text) => handleChange('password', text)}
onSubmitEditing={() => otpRef.current?.focus()}
/>
{errors?.password && <Text className="text-sm text-destructive">{errors?.password}</Text>}
</View>

<View className="gap-1.5">
<Label htmlFor="otp">OTP Code</Label>
<Input
id="otp"
placeholder="Enter 6-digit code"
keyboardType="number-pad"
editable={!isPending}
value={form.otp}
onChangeText={(text) => handleChange('otp', text)}
returnKeyType="done"
submitBehavior="submit"
maxLength={6}
ref={otpRef}
/>
{errors?.otp && <Text className="text-sm text-destructive">{errors?.otp}</Text>}
</View>
<GoldGradient>
<Button className="bg-transparent w-full" onPress={handleSubmit} disabled={isPending}>
{isPending ? (
<ActivityIndicator color={colorScheme === 'dark' ? '#000000' : '#ffffff'} />
) : (
<Text>Reset Password</Text>
)}
</Button>
</GoldGradient>
</View>
</CardContent>
</Card>
</View>
</View>
</ScrollView>
<BottomSheet isOpen={isModalOpen}>
<View className="bg-green-100 w-16 h-16 rounded-full items-center justify-center self-center mb-4">
<IconSymbol name="checkmark.circle" size={24} color="#047857" />
</View>
<Text className="text-center">Password reset successfully!</Text>
<Button className="bg-transparent w-full" onPress={handleCompleteModal}>
<Text>Continue</Text>
<IconSymbol
name="arrow.forward"
size={16}
className="ml-2"
color={colorScheme === 'dark' ? '#000000' : '#ffffff'}
/>
</Button>
</BottomSheet>
</KeyboardAvoidingView>
);
};

export default ResetPassword;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Prettier warning is currently blocking CI.

Please run formatter on this file to resolve the pipeline warning.

🧰 Tools
🪛 GitHub Actions: Mobile CI

[warning] 1-1: Prettier formatting issues detected. Run 'npx prettier --write' to fix code style issues in this file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/screens/auth/reset-password.tsx` around lines 1 - 147, The file fails
CI due to Prettier formatting; run the project's formatter (e.g., yarn prettier
--write or npm run format) on this file to fix style issues, then commit the
formatted changes. Target the ResetPassword component file (symbols:
ResetPassword, useForm, useResetPassword, handleSubmit) so the export default
ResetPassword remains unchanged and no logic is altered—only
whitespace/formatting should be updated.

Copy link
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

🧹 Nitpick comments (3)
mobile/components/ui/bottom-sheet.tsx (1)

48-51: Use the custom Text component for consistent styling.

Line 50 uses the native Text component from react-native with a className prop. While NativeWind may handle this, the project has a custom Text component at @/components/reusables/ui/text used elsewhere in auth screens. Using it here ensures consistent typography and styling behavior.

💡 Proposed fix
-import { Modal, Pressable, ScrollView, Text, useColorScheme, useWindowDimensions, View } from 'react-native';
+import { Modal, Pressable, ScrollView, useColorScheme, useWindowDimensions, View } from 'react-native';
+import { Text } from '@/components/reusables/ui/text';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/ui/bottom-sheet.tsx` around lines 48 - 51, Replace the
native react-native Text usage with the project's custom Text component to
ensure consistent typography: import Text from "@/components/reusables/ui/text"
at the top of bottom-sheet.tsx and change the JSX in the title block (the
conditional that renders {title}) to use that Text component instead of the
native one while preserving the existing props/className and surrounding View;
update any existing import of Text from 'react-native' to avoid duplicate
imports.
mobile/constants/theme.ts (1)

37-37: Consider removing redundant comment and clarifying naming.

The inline comment // 48 80% 50% duplicates the HSL values already present in the string. Additionally, having Colors.icon alongside Colors.light.icon and Colors.dark.icon may cause confusion for developers. Consider a more descriptive name like accentIcon or goldIcon to clarify its purpose.

💡 Suggested improvement
-  icon: 'hsl(48 80% 50%)', // 48 80% 50%
+  accentIcon: 'hsl(48 80% 50%)',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/constants/theme.ts` at line 37, Remove the redundant inline comment
and rename the ambiguous Colors.icon to a more descriptive identifier (e.g.,
accentIcon or goldIcon) to avoid confusion with Colors.light.icon and
Colors.dark.icon; update all references where Colors.icon is used (in the
constants export and any consumers) to the new name and ensure the HSL string
remains the same.
mobile/screens/auth/login.tsx (1)

96-104: Consider completing the keyboard flow by submitting on password field.

The password input has returnKeyType="send" but lacks an onSubmitEditing handler to trigger form submission. Adding this would allow users to complete the entire login flow without leaving the keyboard.

💡 Proposed enhancement
                     <Input
                       id="password"
                       secureTextEntry
                       returnKeyType="send"
                       editable={!isPending}
                       value={form.password}
                       onChangeText={(text) => handleChange('password', text)}
                       ref={passwordRef}
+                      onSubmitEditing={handleSubmit}
                     />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/screens/auth/login.tsx` around lines 96 - 104, The password Input
currently sets returnKeyType="send" but doesn't submit the form—add an
onSubmitEditing handler on the Input (the one with id="password" and
ref={passwordRef}) that triggers the existing form submit flow (call the same
function used to submit elsewhere, e.g., handleSubmit or the login submit
handler) and respect isPending (no-op if isPending) so pressing Send on the
keyboard completes the login flow from the keyboard.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mobile/components/ui/bottom-sheet.tsx`:
- Around line 38-46: The drag handle View in bottom-sheet.tsx has no
backgroundColor, making it invisible; update the View's style (the handle View
inside the BottomSheet component) to include a visible backgroundColor (e.g., a
neutral gray or theme handle color) while keeping width:40, height:4,
borderRadius:2 and marginBottom:16 so the handle is visible but unchanged in
layout.

---

Nitpick comments:
In `@mobile/components/ui/bottom-sheet.tsx`:
- Around line 48-51: Replace the native react-native Text usage with the
project's custom Text component to ensure consistent typography: import Text
from "@/components/reusables/ui/text" at the top of bottom-sheet.tsx and change
the JSX in the title block (the conditional that renders {title}) to use that
Text component instead of the native one while preserving the existing
props/className and surrounding View; update any existing import of Text from
'react-native' to avoid duplicate imports.

In `@mobile/constants/theme.ts`:
- Line 37: Remove the redundant inline comment and rename the ambiguous
Colors.icon to a more descriptive identifier (e.g., accentIcon or goldIcon) to
avoid confusion with Colors.light.icon and Colors.dark.icon; update all
references where Colors.icon is used (in the constants export and any consumers)
to the new name and ensure the HSL string remains the same.

In `@mobile/screens/auth/login.tsx`:
- Around line 96-104: The password Input currently sets returnKeyType="send" but
doesn't submit the form—add an onSubmitEditing handler on the Input (the one
with id="password" and ref={passwordRef}) that triggers the existing form submit
flow (call the same function used to submit elsewhere, e.g., handleSubmit or the
login submit handler) and respect isPending (no-op if isPending) so pressing
Send on the keyboard completes the login flow from the keyboard.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8526ba0 and 8d41683.

📒 Files selected for processing (6)
  • mobile/components/ui/bottom-sheet.tsx
  • mobile/constants/theme.ts
  • mobile/screens/auth/login.tsx
  • mobile/screens/auth/register.tsx
  • mobile/screens/auth/reset-password.tsx
  • mobile/screens/auth/verify-email.tsx
✅ Files skipped from review due to trivial changes (1)
  • mobile/screens/auth/register.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • mobile/screens/auth/reset-password.tsx

@Cysteine12
Copy link
Owner Author

/gemini review

Copy link
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

Caution

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

⚠️ Outside diff range comments (1)
mobile/components/reusables/ui/button.tsx (1)

1-107: ⚠️ Potential issue | 🟡 Minor

Resolve CI formatting failure before merge.

Pipeline reports Prettier violations in this file; please run formatter and commit the result.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/reusables/ui/button.tsx` around lines 1 - 107, Run the
project's Prettier formatter on mobile/components/reusables/ui/button.tsx and
commit the formatted file to resolve CI failures; ensure you format the entire
file (including the cva definitions buttonVariants and buttonTextVariants, the
Button component, and the ScalePressable import/usage) so the spacing, trailing
commas, and line breaks match project Prettier rules and eliminate the reported
violations.
🧹 Nitpick comments (3)
mobile/screens/auth/reset-password.tsx (2)

43-49: Consider handling login failure after successful password reset.

If login fails (network error, rate limiting, etc.), the user receives no feedback and may be left without navigation. Since the password reset succeeded, the user should still be able to proceed to the login screen.

💡 Suggested improvement
+ const { mutate: login, isError: isLoginError } = useLogin();
  // ...

+ useEffect(() => {
+   if (isLoginError) {
+     router.replace('/login');
+   }
+ }, [isLoginError]);

Alternatively, pass onError to the login mutation or use a fallback redirect to /login after a timeout.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/screens/auth/reset-password.tsx` around lines 43 - 49, The
handleCompleteModal function currently calls login({ email: form.email,
password: form.password }) but does not handle failures, leaving the user stuck
if the mutation errors; update handleCompleteModal to handle both success and
failure by using the login mutation's onSuccess/onError callbacks or awaiting
its promise and catching errors, and in the onError (or catch) ensure you show
user feedback (toast or error state) and perform a fallback
router.replace('/login') after an error or after a short timeout; reference the
handleCompleteModal function, the login mutation call, and router.replace to
implement the error handler and optional fallback redirect.

114-120: Consider extracting hardcoded colors to theme constants.

The ActivityIndicator uses inline hex colors that could be replaced with theme constants for consistency with the rest of the codebase.

♻️ Suggested improvement
+ import { Colors } from '@/constants/theme';
  // ...
- <ActivityIndicator color={colorScheme === 'dark' ? '#000000' : '#ffffff'} />
+ <ActivityIndicator color={colorScheme === 'dark' ? Colors.dark.background : Colors.light.background} />

Apply similar pattern to line 130 for the checkmark icon color.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/screens/auth/reset-password.tsx` around lines 114 - 120, Replace the
inline hex color usage in the ActivityIndicator (inside the Button that calls
handleSubmit and reads isPending) with the app's theme color constants instead
of hardcoded '#000000' and '#ffffff'; pull the appropriate color from the theme
(e.g., theme.colors.text or theme.colors.primary depending on dark/light mode)
via the existing colorScheme or useTheme hook and pass that constant to
ActivityIndicator. Do the same for the checkmark icon color referenced near the
checkmark rendering (around line with checkmark icon) so both spinner and icon
use consistent theme constants rather than hardcoded hex values.
mobile/components/reusables/ui/scale-pressable.tsx (1)

10-10: Fix ref contract violation: implement forwardRef or remove RefAttributes declaration.

The component declares RefAttributes<typeof Pressable> on line 10 but isn't wrapped in forwardRef, so any ref passed to ScalePressable will be silently ignored. Either implement proper ref forwarding using forwardRef and passing the ref to the inner Pressable component, or remove RefAttributes from the type signature.

Recommended approach: wrap the component with forwardRef, accept ref as the second parameter, and pass it to the <Pressable> element. Add displayName after the component definition.

Note: The same pattern exists in multiple components (Button, Card subcomponents) with the same violation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/reusables/ui/scale-pressable.tsx` at line 10, The component
ScalePressable currently declares RefAttributes<typeof Pressable> but doesn't
forward refs, causing a ref contract violation; wrap the component in
React.forwardRef, change the component signature to accept (props, ref), pass
that ref to the inner Pressable element, and export the forwarded component (set
a displayName, e.g. ScalePressable.displayName = 'ScalePressable') so refs
passed to ScalePressable reach the underlying Pressable; alternatively remove
RefAttributes from the type if you intentionally do not support refs—prefer the
forwardRef fix and apply the same pattern to other components (Button, Card
subcomponents) with the same issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mobile/components/reusables/ui/scale-pressable.tsx`:
- Around line 5-6: The component currently discards caller-provided
onPressIn/onPressOut by destructuring them as unused (_) and (__) and replacing
them with internal animation handlers; restore and forward the original
callbacks by capturing the props onPressIn and onPressOut (not as _/__) and,
inside your internal handlers (e.g., pressIn handler at the place where you
trigger the press-in animation and the pressOut handler at line ~32), invoke the
animation logic first or last as intended and then call the preserved callbacks
with the original event args (or await/return their values if needed). Ensure
both handlers pass through the event parameter and guard for undefined (if
(onPressIn) onPressIn(e)), so consumers’ side effects still run.

---

Outside diff comments:
In `@mobile/components/reusables/ui/button.tsx`:
- Around line 1-107: Run the project's Prettier formatter on
mobile/components/reusables/ui/button.tsx and commit the formatted file to
resolve CI failures; ensure you format the entire file (including the cva
definitions buttonVariants and buttonTextVariants, the Button component, and the
ScalePressable import/usage) so the spacing, trailing commas, and line breaks
match project Prettier rules and eliminate the reported violations.

---

Nitpick comments:
In `@mobile/components/reusables/ui/scale-pressable.tsx`:
- Line 10: The component ScalePressable currently declares RefAttributes<typeof
Pressable> but doesn't forward refs, causing a ref contract violation; wrap the
component in React.forwardRef, change the component signature to accept (props,
ref), pass that ref to the inner Pressable element, and export the forwarded
component (set a displayName, e.g. ScalePressable.displayName =
'ScalePressable') so refs passed to ScalePressable reach the underlying
Pressable; alternatively remove RefAttributes from the type if you intentionally
do not support refs—prefer the forwardRef fix and apply the same pattern to
other components (Button, Card subcomponents) with the same issue.

In `@mobile/screens/auth/reset-password.tsx`:
- Around line 43-49: The handleCompleteModal function currently calls login({
email: form.email, password: form.password }) but does not handle failures,
leaving the user stuck if the mutation errors; update handleCompleteModal to
handle both success and failure by using the login mutation's onSuccess/onError
callbacks or awaiting its promise and catching errors, and in the onError (or
catch) ensure you show user feedback (toast or error state) and perform a
fallback router.replace('/login') after an error or after a short timeout;
reference the handleCompleteModal function, the login mutation call, and
router.replace to implement the error handler and optional fallback redirect.
- Around line 114-120: Replace the inline hex color usage in the
ActivityIndicator (inside the Button that calls handleSubmit and reads
isPending) with the app's theme color constants instead of hardcoded '#000000'
and '#ffffff'; pull the appropriate color from the theme (e.g.,
theme.colors.text or theme.colors.primary depending on dark/light mode) via the
existing colorScheme or useTheme hook and pass that constant to
ActivityIndicator. Do the same for the checkmark icon color referenced near the
checkmark rendering (around line with checkmark icon) so both spinner and icon
use consistent theme constants rather than hardcoded hex values.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d41683 and f4a1a36.

📒 Files selected for processing (6)
  • mobile/components/reusables/ui/button.tsx
  • mobile/components/reusables/ui/scale-pressable.tsx
  • mobile/components/ui/bottom-sheet.tsx
  • mobile/constants/theme.ts
  • mobile/screens/auth/login.tsx
  • mobile/screens/auth/reset-password.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • mobile/constants/theme.ts
  • mobile/components/ui/bottom-sheet.tsx
  • mobile/screens/auth/login.tsx

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request introduces a new Reset Password screen and integrates the logic for password reset. It also includes a new ScalePressable component for animated buttons and a BottomSheet component for displaying success messages. Minor UI adjustments were made to other authentication screens, such as updating button text and adding font weights. The changes generally improve the user experience by providing a dedicated password reset flow and enhancing interactive elements.

@Cysteine12
Copy link
Owner Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully implements the reset password user interface and integrates the corresponding logic. The introduction of a reusable BottomSheet and an animated ScalePressable component are nice additions. My review includes a few suggestions to enhance performance, ensure consistency across screens, and adhere to React best practices. Overall, this is a solid contribution.

@Cysteine12 Cysteine12 merged commit 3003375 into develop Feb 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request mobile Changes involving the mobile application

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M: Build Auth UI

1 participant