feat(reset-password): setup ui & integrate logic#118
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, 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
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 | 🟡 MinorPrettier 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
📒 Files selected for processing (8)
mobile/app/(auth)/_layout.tsxmobile/app/(auth)/reset-password.tsxmobile/components/ui/bottom-sheet.tsxmobile/components/ui/icon-symbol.tsxmobile/features/auth/hook.tsmobile/screens/auth/forgot-password.tsxmobile/screens/auth/login.tsxmobile/screens/auth/reset-password.tsx
| 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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Textcomponent fromreact-nativewith aclassNameprop. While NativeWind may handle this, the project has a customTextcomponent at@/components/reusables/ui/textused 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, havingColors.iconalongsideColors.light.iconandColors.dark.iconmay cause confusion for developers. Consider a more descriptive name likeaccentIconorgoldIconto 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 anonSubmitEditinghandler 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
📒 Files selected for processing (6)
mobile/components/ui/bottom-sheet.tsxmobile/constants/theme.tsmobile/screens/auth/login.tsxmobile/screens/auth/register.tsxmobile/screens/auth/reset-password.tsxmobile/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
|
/gemini review |
There was a problem hiding this comment.
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 | 🟡 MinorResolve 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
loginfails (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
onErrorto the login mutation or use a fallback redirect to/loginafter 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: implementforwardRefor removeRefAttributesdeclaration.The component declares
RefAttributes<typeof Pressable>on line 10 but isn't wrapped inforwardRef, so anyrefpassed toScalePressablewill be silently ignored. Either implement proper ref forwarding usingforwardRefand passing the ref to the innerPressablecomponent, or removeRefAttributesfrom the type signature.Recommended approach: wrap the component with
forwardRef, acceptrefas the second parameter, and pass it to the<Pressable>element. AdddisplayNameafter 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
📒 Files selected for processing (6)
mobile/components/reusables/ui/button.tsxmobile/components/reusables/ui/scale-pressable.tsxmobile/components/ui/bottom-sheet.tsxmobile/constants/theme.tsmobile/screens/auth/login.tsxmobile/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
There was a problem hiding this comment.
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.
|
/gemini review |
There was a problem hiding this comment.
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.
📌 Summary
🎯 Why is this change needed?
Closes #78
🧠 What was changed?
🏗️ Type of Change
🧪 How was this tested?
Test details:
📸 Screenshots / API Samples (if applicable)
Summary by CodeRabbit
New Features
Usability
Style