Skip to content

feat: misc frontend UI fixes and improvements#56

Closed
cole-hackman wants to merge 2 commits intodevfrom
feature/misc-ui-changes
Closed

feat: misc frontend UI fixes and improvements#56
cole-hackman wants to merge 2 commits intodevfrom
feature/misc-ui-changes

Conversation

@cole-hackman
Copy link
Copy Markdown
Collaborator

@cole-hackman cole-hackman commented Mar 11, 2026

Linked Issues

No linked Linear issue — miscellaneous UI polish.

Summary

A collection of frontend UI fixes and quality-of-life improvements for the PolyBuys marketplace.

Profile tab (settings.tsx):

  • Removed duplicate sign-in messages when logged out (Session card now only shows when authenticated)
  • Styled all profile TextInput placeholder text with lighter grey (#9aaa9f)
  • Changed Year field from pre-filled "2026" to empty with placeholder

Home feed (index.tsx):

  • Unauthenticated users clicking "+ Create Listing" are now redirected to profile tab on web (retains native Alert behavior)
  • Standardized Create Listing button color to brand green (#154734)

Listing detail ([id].tsx):

  • Fixed browser tab title persisting after navigating away from a listing (cleanup resets to "PolyBuys")
  • Category and condition values now display with proper capitalization via capitalize() helper

Create listing (new.tsx):

  • Added cross-platform showAlert() helper — uses window.alert() on web since Alert.alert is invisible in Expo web
  • Replaced all Alert.alert calls with showAlert so validation messages actually appear on web
  • Added upfront profile check — queries profile on mount and blocks submission with friendly message if incomplete
  • Added visible yellow warning banner when profile is missing, with tap-to-navigate to Profile tab
  • Styled placeholder text with lighter grey to match profile page

My Listings (my-listings.tsx):

  • Added red Delete button to each listing card with confirmation dialog
  • Uses window.confirm() on web, native Alert with Cancel/Delete on mobile
  • Shows loading spinner during deletion, hides button for already-deleted listings

Summary by CodeRabbit

  • New Features
    • Delete listings with confirmation and loading state
    • Guided profile setup flow when creating listings; prevents submission until profile is ready
  • Bug Fixes
    • Platform-specific unauthenticated flow: web now redirects to settings, native retains login prompt
    • Session section only shown when authenticated
  • Style
    • Updated create button color and placeholder text color
    • Capitalized listing category/condition and improved page title handling

- Fix duplicate sign-in messages on profile tab
- Redirect unauthenticated users to profile on Create Listing (web)
- Fix browser tab title persisting after leaving a listing
- Style placeholder text with lighter grey across profile and create listing forms
- Standardize Create Listing button to brand green (#154734)
- Capitalize category and condition values on listing detail page
- Add profile setup check before creating listings with visible warning banner
- Replace Alert.alert with cross-platform showAlert for web compatibility
- Add Delete button to My Listings with confirmation dialog
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

Platform-specific unauthenticated create flow (web → /settings, native → alert), added listing deletion with confirmation and loading state, unified cross-platform showAlert utility, profile-gated listing creation with banner and pre-submit checks, settings placeholder/style tweaks, and web document.title management for listings.

Changes

Cohort / File(s) Summary
Navigation / Create Button
frontend/app/(tabs)/index.tsx
Platform-specific unauthenticated create flow: web navigates to /settings, native shows alert. Create button color changed from #1c7f50 to #154734.
My Listings (Delete)
frontend/app/(tabs)/my-listings.tsx
Adds useMutation-driven deleteListing flow, deletingId state, cross-platform confirmation (confirm/Alert), error handling via showAlert, and delete button with loading styles.
Create Listing (Profile Guards & Alerts)
frontend/app/listings/new.tsx, frontend/utils/showAlert.ts
Introduces showAlert utility, queries current profile, adds pre-submit profile loading/null guards with banner/alerts, replaces many Alert calls with showAlert, and updates input placeholder styling.
Settings Form UI
frontend/app/(tabs)/settings.tsx
Changes default year to '', adds placeholderTextColor to inputs, and conditionally renders session UI only for authenticated users.
Listing Details (Web title + UI helpers)
frontend/app/listings/[id].tsx
Adds capitalize() helper for category/condition display and updates document.title on web to include listing title, reverting on cleanup.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as Client UI
  participant ProfileQ as Profile Query (Convex)
  participant API as Listings Mutation (Convex)
  participant Alert as showAlert / Native Alert

  User->>UI: Click "Create Listing"
  UI->>ProfileQ: fetch currentProfile
  ProfileQ-->>UI: currentProfile (undefined/null/object)
  alt profile undefined
    UI->>Alert: "Please wait — loading profile"
  else profile null
    UI->>Alert: "Complete profile" 
    UI-->>User: show profile banner / navigate to Profile
  else profile present
    UI->>API: createListing(payload)
    API-->>UI: success / error
    alt success
      UI->>Alert: "Listing created"
    else error
      UI->>Alert: show error message (possibly PROFILE_SETUP_ERROR)
    end
  end
Loading
sequenceDiagram
  participant User
  participant UI as MyListings UI
  participant Confirm as confirm() / Alert
  participant API as deleteListing Mutation (Convex)
  participant Alert as showAlert

  User->>UI: Click "Delete" on a listing
  UI->>Confirm: confirm dialog (web) / Alert.alert (native)
  alt confirmed
    UI->>API: deleteListing(listingId)
    API-->>UI: success / error
    alt success
      UI-->>User: remove item / update state
    else error
      UI->>Alert: show error message
    end
  else cancelled
    UI-->>User: no-op
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hopped through code with nimble paws,

Alerts now sing on web and apps,
I pruned old posts with tidy claws,
Banners guide where profiles lapse,
Titles twinkle — browse with glee!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and uses generic terms like 'misc' that do not clearly convey the specific changes; it lacks concreteness about what UI fixes and improvements are included. Consider a more descriptive title that highlights primary changes, such as 'feat: improve UX for auth flow, listing creation, and deletion' or similar to better represent the substantial changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all required sections: linked issues, summary with detailed changes organized by area, and how-to-test instructions; however, the checklist section is missing.

✏️ 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/misc-ui-changes

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

64-80: Keep the signed-out reset aligned with the new empty year default.

This branch still hard-codes '2026', which fights the placeholder-only flow you introduced above. Resetting to '' here too keeps every entry path consistent.

Suggested cleanup
   setLoadedProfileKey(null);
   setName('');
   setEmail('');
   setBio('');
   setMajor('');
-  setYear('2026');
+  setYear('');
 }, [isAuthenticated]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/`(tabs)/settings.tsx around lines 64 - 80, The signed-out reset
in the useEffect should use the new empty-year default instead of the hard-coded
'2026': update the branch that runs when !isAuthenticated to call setYear('')
(alongside setLoadedProfileKey(null), setName(''), setEmail(''), setBio(''),
setMajor('')) so the reset behavior matches the placeholder-only flow introduced
earlier.
frontend/app/listings/new.tsx (1)

27-33: Consider promoting showAlert into a shared dialog helper.

frontend/app/(tabs)/my-listings.tsx now has the same web/native branching for browser dialogs. Pulling this into a small shared util would keep cross-platform messaging consistent and avoid a third copy later.

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

In `@frontend/app/listings/new.tsx` around lines 27 - 33, Extract the duplicated
showAlert implementation into a small shared utility (e.g., export a showAlert
function from a new module) and update both usages to import that single helper;
specifically, move the logic in the showAlert function (the Platform.OS ===
'web' window.alert branch and the Alert.alert branch) into the new shared
function, ensure the new module imports Platform and Alert (and references
window safely), export showAlert, and then replace the local showAlert
implementations in component files (including the one currently named showAlert)
with imports from the shared util so behavior remains identical across
web/native.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/app/`(tabs)/my-listings.tsx:
- Around line 42-74: The UI allows starting multiple deletes concurrently
because only deletingId tracks a single row; fix by preventing new deletes while
a delete mutation is in flight: in handleDelete (and the delete button disabled
logic) short-circuit and return immediately if deleteListing.isLoading or a new
boolean isDeleting flag is true, and set that flag (or rely on
deleteListing.isLoading) at the start of handleDelete and clear it in finally;
update any delete-button disabled/ spinner conditions to use
(deleteListing.isLoading || deletingId !== null) so all delete buttons are
disabled while a delete is pending and the spinner stays consistent with
deletingId.

---

Nitpick comments:
In `@frontend/app/`(tabs)/settings.tsx:
- Around line 64-80: The signed-out reset in the useEffect should use the new
empty-year default instead of the hard-coded '2026': update the branch that runs
when !isAuthenticated to call setYear('') (alongside setLoadedProfileKey(null),
setName(''), setEmail(''), setBio(''), setMajor('')) so the reset behavior
matches the placeholder-only flow introduced earlier.

In `@frontend/app/listings/new.tsx`:
- Around line 27-33: Extract the duplicated showAlert implementation into a
small shared utility (e.g., export a showAlert function from a new module) and
update both usages to import that single helper; specifically, move the logic in
the showAlert function (the Platform.OS === 'web' window.alert branch and the
Alert.alert branch) into the new shared function, ensure the new module imports
Platform and Alert (and references window safely), export showAlert, and then
replace the local showAlert implementations in component files (including the
one currently named showAlert) with imports from the shared util so behavior
remains identical across web/native.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 62842e70-82e4-4908-965e-4917ea5e36f8

📥 Commits

Reviewing files that changed from the base of the PR and between 37735cc and 3e92aa6.

📒 Files selected for processing (5)
  • frontend/app/(tabs)/index.tsx
  • frontend/app/(tabs)/my-listings.tsx
  • frontend/app/(tabs)/settings.tsx
  • frontend/app/listings/[id].tsx
  • frontend/app/listings/new.tsx

Comment thread frontend/app/(tabs)/my-listings.tsx
- Extract showAlert into shared utils/showAlert.ts module
- Prevent concurrent deletes in my-listings (guard + disable all buttons)
- Fix year reset to empty string in settings signed-out useEffect
- Remove unused Alert/Platform imports from new.tsx
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/app/(tabs)/my-listings.tsx (1)

68-69: Consider extracting the actual error message for better user feedback.

The catch block discards the error details and shows a generic message. The backend's verifyOwnership can return specific errors like "Listing not found" or "You are not the owner" which would be more informative to users.

💡 Proposed improvement
-    } catch {
-      showAlert('Error', 'Failed to delete listing. Please try again.');
+    } catch (error) {
+      const message = error instanceof Error ? error.message : 'Failed to delete listing. Please try again.';
+      showAlert('Error', message);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/`(tabs)/my-listings.tsx around lines 68 - 69, The catch block in
the delete flow currently swallows the error and shows a generic alert; update
the delete handler (the function that calls verifyOwnership / deleteListing and
calls showAlert) to catch the error as a variable (e.g., catch (err)) and
extract a useful message (err.message || err?.data?.message || String(err)) to
pass into showAlert so users see backend messages like "Listing not found" or
"You are not the owner", while keeping a fallback generic message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/app/`(tabs)/my-listings.tsx:
- Around line 68-69: The catch block in the delete flow currently swallows the
error and shows a generic alert; update the delete handler (the function that
calls verifyOwnership / deleteListing and calls showAlert) to catch the error as
a variable (e.g., catch (err)) and extract a useful message (err.message ||
err?.data?.message || String(err)) to pass into showAlert so users see backend
messages like "Listing not found" or "You are not the owner", while keeping a
fallback generic message.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b8d05991-7ba8-4cf1-a602-a46373649259

📥 Commits

Reviewing files that changed from the base of the PR and between 3e92aa6 and 4114d61.

📒 Files selected for processing (4)
  • frontend/app/(tabs)/my-listings.tsx
  • frontend/app/(tabs)/settings.tsx
  • frontend/app/listings/new.tsx
  • frontend/utils/showAlert.ts

@evan-taylor
Copy link
Copy Markdown
Collaborator

Thanks cole! I merged your branch into my branch and fixed conflicts, since I was doing a UI overhaul. Closing this one as your changes will get merged with mine!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants