Skip to content

Refactor input components to use LabeledInput for better consistency … - #177

Merged
LuisAll12 merged 4 commits into
devfrom
feature/identic-inputs
May 1, 2026
Merged

LuisAll12 merged 4 commits into
devfrom
feature/identic-inputs

Conversation

@LuisAll12

@LuisAll12 LuisAll12 commented May 1, 2026 •

Copy link
Copy Markdown
Collaborator

…and readability

  • Replaced Input with LabeledInput in various registration and profile settings screens.
  • Updated styles for LabeledInput to match the design specifications.
  • Removed redundant input styling and encapsulated it within LabeledInput.
  • Enhanced error handling display for inputs in the registration and profile forms.

Summary by CodeRabbit

  • New Features

    • Added full-screen photo viewer for profile galleries
    • Enhanced photo management with upload, delete, and confirmation features
    • Added loading skeleton screens during data retrieval
  • Bug Fixes

    • Improved form error message display across authentication and settings screens
    • Enhanced error handling for profile and photo operations
  • Improvements

    • Standardized form input styling and labels for consistency across the app
    • Adjusted spacing and layout for better visual hierarchy

…and readability

- Replaced Input with LabeledInput in various registration and profile settings screens.
- Updated styles for LabeledInput to match the design specifications.
- Removed redundant input styling and encapsulated it within LabeledInput.
- Enhanced error handling display for inputs in the registration and profile forms.
@LuisAll12 LuisAll12 added this to the Sprint3 milestone May 1, 2026
@LuisAll12 LuisAll12 self-assigned this May 1, 2026
@LuisAll12 LuisAll12 added enhancement New feature or request Feature labels May 1, 2026
@coderabbitai

coderabbitai Bot commented May 1, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

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

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6f289c7b-2177-4780-91bb-f7afa6ba2794

📥 Commits

Reviewing files that changed from the base of the PR and between 4850ee0 and 4db1f6a.

📒 Files selected for processing (2)
  • app/(protected)/settings/personaldetails.tsx
  • components/PhoneNumberInput.tsx
📝 Walkthrough

Walkthrough

The PR introduces a new LabeledInput component and refactors multiple authentication, registration, and profile pages to use it instead of custom Input and Field components, consolidating form field styling, error handling, and label rendering. One file also adds server-backed photo gallery management with upload, delete, and lightbox functionality.

Changes

Cohort / File(s) Summary
New Labeled Input Component
components/LabeledInput.tsx, components/input.tsx
Introduces LabeledInput component with integrated label and error rendering; updates Input styling with borderless, rounded design and increased padding.
Login Form Refactoring
app/(auth)/login/forgot-password.tsx, app/(auth)/login/withEmail.tsx, app/(auth)/login/withPhoneNumber.tsx
Migrates email, phone, password, and verification code inputs from Input to LabeledInput; removes inline error Text blocks; consolidates error handling via props.
Registration Form Refactoring
app/(auth)/register/addProfileData.tsx, app/(auth)/register/password.tsx, app/(auth)/register/withEmail.tsx
Replaces custom Field and Input components with LabeledInput across profile data, password, and email fields; standardizes error rendering and label display.
Settings & Profile Refactoring
app/(protected)/settings/security.tsx, app/complete-profile/name.tsx, app/complete-profile/personalDetails.tsx
Converts manual labeled input UI patterns to LabeledInput component; removes runtime style factories and custom wrappers.
Advanced Photo Gallery
app/(protected)/settings/personaldetails.tsx
Introduces server-backed photo management with async load/upload/delete flows; adds lightbox modal viewer with animated skeleton loaders and per-photo deletion confirmation UI.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Jamie-Poeffel

Poem

🐰 A Label here, an Input there,
Now bundled snugly without a care!
No scattered fields to chase and find,
LabeledInput unified in mind!
From auth to profile, forms now shine,
This refactor's quite divine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: refactoring input components to use a consolidated LabeledInput component across multiple screens for consistency.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/identic-inputs

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
Review rate limit: 0/1 reviews remaining, refill in 15 minutes and 21 seconds.

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

@Jamie-Poeffel
Jamie-Poeffel self-requested a review May 1, 2026 11:48
Jamie-Poeffel
Jamie-Poeffel previously approved these changes May 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
components/LabeledInput.tsx (1)

48-59: ⚡ Quick win

Keep the base input style in one place.

components/input.tsx:33-44 already owns the same height/radius/padding/background block, so restating it here creates an easy drift point. Let Input provide the default field chrome and only merge caller-specific overrides from style.

Suggested simplification
             <Input
                 {...props}
-                style={[
-                    {
-                        height: 52,
-                        borderWidth: 0,
-                        borderRadius: 18,
-                        paddingHorizontal: 16,
-                        fontSize: 15,
-                        marginTop: 0,
-                        backgroundColor: theme.card,
-                    },
-                    style,
-                ]}
+                style={style}
             />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/LabeledInput.tsx` around lines 48 - 59, The LabeledInput file
duplicates the base input chrome (height, borderRadius, paddingHorizontal,
backgroundColor) that Input already defines in components/input.tsx; remove
those hard-coded defaults from LabeledInput's inline style and let the Input
component provide its default chrome, only merging the consumer-provided style
prop, e.g. keep the style array but drop the base block so LabeledInput passes
through style overrides to Input; reference the LabeledInput component and the
Input component in components/input.tsx when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/`(auth)/login/forgot-password.tsx:
- Around line 177-200: The shared error string is only rendered on the
confirm-password LabeledInput, so when onSubmitNewPassword() validates the new
password length the message appears under the wrong field; change the error
handling to track and render per-field errors (either add two states like
newPasswordError and confPasswordError or make error an object {newPassword,
confPassword}), update the onChangeText handlers to clear the corresponding
field error (e.g., setNewPassword clears newPasswordError, setConfPassword
clears confPasswordError), and modify onSubmitNewPassword to set the specific
field error (setNewPasswordError or setConfPasswordError) based on which
validation fails, then pass the matching error prop to each LabeledInput
(error={newPasswordError ?? undefined} for the new password input and
error={confPasswordError ?? undefined} for the confirm input).

In `@app/`(auth)/register/password.tsx:
- Around line 92-98: The onChangeText handler for the password field only clears
error.password, leaving a stale "passwords do not match" on error.confPassword;
update the handler in the component where setPasswordInput and setError are used
(the password input onChangeText) to also clear error.confPassword when present
— e.g. inside the existing if block add a check for error.confPassword and call
setError(prev => ({ ...prev, password: undefined, confPassword: undefined })) so
the confirm-field mismatch error is removed as soon as the primary password
changes.

In `@app/`(protected)/settings/personaldetails.tsx:
- Around line 548-563: The email and phone LabeledInput fields (props
value={email} onChangeText={setEmail} and value={phone} onChangeText={setPhone})
are editable but not included in the PATCH sent by handleSaveAndExit; either
include email and phone in the PATCH payload assembled in handleSaveAndExit (add
email and phone alongside firstName, lastName, country, jobTitle, aboutMe,
dateOfBirth) if the API supports updating them, or make the LabeledInput fields
readOnly/disabled so edits cannot be made in the UI; update the code in
handleSaveAndExit (the function that builds the PATCH body) or set the
LabeledInput props to readOnly/disabled to match backend capabilities.

In `@components/LabeledInput.tsx`:
- Around line 46-60: Pass the visible label through to the underlying Input
component and surface the error state for assistive tech: in the LabeledInput
wrapper, provide accessibilityLabel={label} on the Input component and set
accessibilityState={{ invalid: !!error }} (or merge into existing
accessibilityState) so screen readers know the field name and when it's invalid;
keep existing props spread and preserve style.

---

Nitpick comments:
In `@components/LabeledInput.tsx`:
- Around line 48-59: The LabeledInput file duplicates the base input chrome
(height, borderRadius, paddingHorizontal, backgroundColor) that Input already
defines in components/input.tsx; remove those hard-coded defaults from
LabeledInput's inline style and let the Input component provide its default
chrome, only merging the consumer-provided style prop, e.g. keep the style array
but drop the base block so LabeledInput passes through style overrides to Input;
reference the LabeledInput component and the Input component in
components/input.tsx when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8f02cfb3-f1dd-456c-84de-19819c434fb3

📥 Commits

Reviewing files that changed from the base of the PR and between 8c6d3e2 and 4850ee0.

📒 Files selected for processing (12)
  • app/(auth)/login/forgot-password.tsx
  • app/(auth)/login/withEmail.tsx
  • app/(auth)/login/withPhoneNumber.tsx
  • app/(auth)/register/addProfileData.tsx
  • app/(auth)/register/password.tsx
  • app/(auth)/register/withEmail.tsx
  • app/(protected)/settings/personaldetails.tsx
  • app/(protected)/settings/security.tsx
  • app/complete-profile/name.tsx
  • app/complete-profile/personalDetails.tsx
  • components/LabeledInput.tsx
  • components/input.tsx

Comment on lines +177 to +200
<LabeledInput
label={t("newPasswordPlaceholder")}
placeholder="••••••••"
secureTextEntry
textContentType="newPassword"
autoComplete="new-password"
onChangeText={setNewPassword}
onChangeText={(v) => {
setNewPassword(v);
setError(null);
}}
value={newPassword}
/>
<Input
placeholder={t("confirmPasswordPlaceholder")}
<LabeledInput
label={t("confirmPasswordPlaceholder")}
placeholder="••••••••"
secureTextEntry
textContentType="newPassword"
autoComplete="new-password"
onChangeText={setConfPassword}
onChangeText={(v) => {
setConfPassword(v);
setError(null);
}}
value={confPassword}
error={error ?? undefined}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Render the validation error on the field that actually failed.

onSubmitNewPassword() uses one shared error string for both rules, but only the confirm-password field renders it. When the new password is too short, the message shows under the wrong input.

Suggested fix
                             <LabeledInput
                                 label={t("newPasswordPlaceholder")}
                                 placeholder="••••••••"
                                 secureTextEntry
                                 textContentType="newPassword"
                                 autoComplete="new-password"
                                 onChangeText={(v) => {
                                     setNewPassword(v);
                                     setError(null);
                                 }}
                                 value={newPassword}
+                                error={error && newPassword.length < 6 ? error : undefined}
                             />
                             <LabeledInput
                                 label={t("confirmPasswordPlaceholder")}
                                 placeholder="••••••••"
                                 secureTextEntry
                                 textContentType="newPassword"
                                 autoComplete="new-password"
                                 onChangeText={(v) => {
                                     setConfPassword(v);
                                     setError(null);
                                 }}
                                 value={confPassword}
-                                error={error ?? undefined}
+                                error={error && newPassword.length >= 6 ? error : undefined}
                             />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(auth)/login/forgot-password.tsx around lines 177 - 200, The shared
error string is only rendered on the confirm-password LabeledInput, so when
onSubmitNewPassword() validates the new password length the message appears
under the wrong field; change the error handling to track and render per-field
errors (either add two states like newPasswordError and confPasswordError or
make error an object {newPassword, confPassword}), update the onChangeText
handlers to clear the corresponding field error (e.g., setNewPassword clears
newPasswordError, setConfPassword clears confPasswordError), and modify
onSubmitNewPassword to set the specific field error (setNewPasswordError or
setConfPasswordError) based on which validation fails, then pass the matching
error prop to each LabeledInput (error={newPasswordError ?? undefined} for the
new password input and error={confPasswordError ?? undefined} for the confirm
input).

Comment on lines 92 to +98
onChangeText={(val) => {
setPasswordInput(val);

if (error.password) {
setError((prev) => ({
...prev,
password: undefined,
}));
setError((prev) => ({ ...prev, password: undefined }));
}
}}
error={error.password?.message}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear the mismatch error when the password changes.

confPassword validation depends on both inputs. After a “passwords do not match” error, editing the first field can fix it, but this handler only clears error.password, so the stale confirm error keeps showing until the second field is edited.

Suggested fix
                     onChangeText={(val) => {
                         setPasswordInput(val);
-                        if (error.password) {
-                            setError((prev) => ({ ...prev, password: undefined }));
+                        if (error.password || error.confPassword) {
+                            setError((prev) => ({
+                                ...prev,
+                                password: undefined,
+                                confPassword: undefined,
+                            }));
                         }
                     }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onChangeText={(val) => {
setPasswordInput(val);
if (error.password) {
setError((prev) => ({
...prev,
password: undefined,
}));
setError((prev) => ({ ...prev, password: undefined }));
}
}}
error={error.password?.message}
onChangeText={(val) => {
setPasswordInput(val);
if (error.password || error.confPassword) {
setError((prev) => ({
...prev,
password: undefined,
confPassword: undefined,
}));
}
}}
error={error.password?.message}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(auth)/register/password.tsx around lines 92 - 98, The onChangeText
handler for the password field only clears error.password, leaving a stale
"passwords do not match" on error.confPassword; update the handler in the
component where setPasswordInput and setError are used (the password input
onChangeText) to also clear error.confPassword when present — e.g. inside the
existing if block add a check for error.confPassword and call setError(prev =>
({ ...prev, password: undefined, confPassword: undefined })) so the
confirm-field mismatch error is removed as soon as the primary password changes.

Comment thread app/(protected)/settings/personaldetails.tsx Outdated
Comment on lines +46 to +60
<Input
{...props}
style={[
{
height: 52,
borderWidth: 0,
borderRadius: 18,
paddingHorizontal: 16,
fontSize: 15,
marginTop: 0,
backgroundColor: theme.card,
},
style,
]}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "LabeledInput.tsx" -o -name "input.tsx" | head -20

Repository: MindsofD23b/Frontend-Elysio

Length of output: 124


🏁 Script executed:

cat -n ./components/LabeledInput.tsx

Repository: MindsofD23b/Frontend-Elysio

Length of output: 2293


🏁 Script executed:

cat -n ./components/input.tsx

Repository: MindsofD23b/Frontend-Elysio

Length of output: 1791


Expose the field label to assistive tech.

The visible <Text> label is not associated with the underlying TextInput, so screen readers can land on the field without hearing its name reliably. Since this wrapper now backs multiple auth/profile forms, please pass the label through to Input via accessibilityLabel and mark invalid state when error exists.

Suggested fix
 interface LabeledInputProps extends TextInputProps {
     label: string;
     error?: string;
+    accessibilityLabel?: string;
+    accessibilityState?: any;
     keyboardType?: "default" | "numeric" | "email-address" | "phone-pad";
 export default function LabeledInput({
     label,
     error,
+    accessibilityLabel,
+    accessibilityState,
     style,
     ...props
 }: LabeledInputProps) {
     const { theme } = useTheme();

     return (
         <View style={{ width: "100%", marginTop: 14 }}>
             <Text
                 style={{
                     fontSize: 14,
                     fontWeight: "600",
                     marginBottom: 6,
                     color: theme.primary,
                 }}
             >
                 {label}
             </Text>
             <Input
                 {...props}
+                accessibilityLabel={accessibilityLabel ?? label}
+                accessibilityState={
+                    error
+                        ? { ...(accessibilityState ?? {}), invalid: true }
+                        : accessibilityState
+                }
                 style={[
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/LabeledInput.tsx` around lines 46 - 60, Pass the visible label
through to the underlying Input component and surface the error state for
assistive tech: in the LabeledInput wrapper, provide accessibilityLabel={label}
on the Input component and set accessibilityState={{ invalid: !!error }} (or
merge into existing accessibilityState) so screen readers know the field name
and when it's invalid; keep existing props spread and preserve style.

@LuisAll12
LuisAll12 merged commit a79dd7e into dev May 1, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Elysio Project May 1, 2026
@LuisAll12
LuisAll12 deleted the feature/identic-inputs branch May 4, 2026 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Feature

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants