Skip to content

Refact/homepage#107

Merged
respp merged 9 commits intoStellar-Rent:mainfrom
JoelVR17:refact/homepage
Jul 26, 2025
Merged

Refact/homepage#107
respp merged 9 commits intoStellar-Rent:mainfrom
JoelVR17:refact/homepage

Conversation

@JoelVR17
Copy link
Contributor

@JoelVR17 JoelVR17 commented Jul 23, 2025

StellarRent Logo

Pull Request | StellarRent

📝 Summary

Refact the entire design of the homepage

🔗 Related Issues

Closes #105

🔄 Changes Made

  • ➕ Added logo image to public assets.
  • 🔧 Refactored layout and homepage structure.
  • 🔧 Improved SearchBar component layout and added input validation.
  • ➕ Created RightSidebar with navigation icons and user profile section.
  • 🔧 Refactored PropertyCard and PropertyGrid for better UI and structure.
  • ➕ Introduced IconContainer component for flexible icon rendering.
  • 🔧 Standardized formatting in tailwind.config.js for consistency.
  • 🔧 Updated SearchBar and RightSidebar to use Image component.
  • ➕ Added new icon assets to public directory.

🖼️ Current Output

Provide visual evidence of the changes:
image

⚠️ Potential Risks

None

🚀 Next Steps & Improvements

This change lays a solid foundation for further optimizations. Some areas that could benefit from future improvements include:

  • 🔹 Potential user experience enhancements

💬 Comments

None

Summary by CodeRabbit

  • New Features

    • Introduced a right-aligned sidebar with navigation icons and user profile access.
    • Added an icon container component for consistent icon styling.
  • UI Updates

    • Redesigned homepage with a new header, simplified search section, and updated property display.
    • Overhauled the search bar with a more static, icon-driven layout and simplified validation.
    • Refreshed property cards with a new layout, enhanced details, and improved navigation.
    • Updated property grid to display mock properties in a responsive layout.
  • Style

    • Changed background and text colors for improved contrast.
    • Updated the secondary color in the theme to a fixed hex value.
  • Refactor

    • Simplified and restructured several components for clarity and maintainability.
    • Removed unused sections and components from the homepage and search bar.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 23, 2025

Walkthrough

This update significantly refactors the homepage and related UI components. It introduces a new homepage layout, removes the Navbar, simplifies the SearchBar by eliminating autocomplete and interactive date selection, and redesigns the PropertyCard and PropertyGrid components. New components such as RightSidebar and IconContainer are added. Tailwind color configuration is updated.

Changes

File(s) Change Summary
apps/web/src/app/layout.tsx Reformatted imports, removed Navbar, updated font and metadata quotes, changed body/background colors, adjusted main styling.
apps/web/src/app/page.tsx Refactored homepage: removed old sections, added new header, search, properties section, and RightSidebar. Updated imports and layout.
apps/web/src/components/features/search/SearchBar.tsx Major refactor: removed autocomplete, simplified validation and UI, replaced inputs with icon-driven layout, restyled error display, removed submit button.
apps/web/src/components/layout/RightSidebar.tsx New component: fixed right sidebar with vertical icon buttons and user avatar, styled with utility classes and Next.js Image.
apps/web/src/components/search/PropertyCard.tsx Refactored: now receives a single property object, removed image error/loading handling, redesigned layout, added verified badge, updated details display, changed button to link.
apps/web/src/components/search/PropertyGrid.tsx Refactored: removed props and infinite scroll, now uses internal mock data, simplified to static grid rendering.
apps/web/src/components/ui/icon-container.tsx New component: IconContainer for consistent icon styling with props for icon and className.
apps/web/tailwind.config.js Changed Tailwind 'secondary' color from HSL CSS variable to fixed hex value.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomePage
    participant SearchBar
    participant PropertyGrid
    participant RightSidebar

    User->>HomePage: Loads homepage
    HomePage->>SearchBar: Renders static search UI
    HomePage->>PropertyGrid: Renders property cards (mock data)
    HomePage->>RightSidebar: Displays sidebar with icons
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

  • Stellar-Rent/stellar-rent#54: Initial homepage implementation with interactive search, autocomplete, and featured properties; overlaps with several refactored components in this PR.

Poem

A homepage reborn, with layout anew,
Sidebar and icons, in elegant view.
Search made simple, cards now refined,
Colors and code, all realigned.
As rabbits, we cheer for this visual delight—
Hopping for joy in the soft morning light! 🐇✨

Note

⚡️ Unit Test Generation - Beta

CodeRabbit's unit test generation is now available in Beta! Automatically generate comprehensive unit tests for your code changes, ensuring better test coverage and catching edge cases you might miss. Our AI analyzes your code structure and creates tests that follow best practices and your project's testing patterns. Learn more here, or just try it under ✨ Finishing Touches.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 12

🔭 Outside diff range comments (1)
apps/web/src/components/features/search/SearchBar.tsx (1)

50-82: Form submission logic exists but will never execute properly

The handleSubmit function validates and processes form data, but since the form has no inputs and the data never changes from initial values, this logic is essentially dead code.

Either:

  1. Implement the missing input fields and submit button
  2. Remove the unused submission logic if this is meant to be a static component

The current state creates confusion about the component's purpose and maintains unnecessary code.

🧹 Nitpick comments (2)
apps/web/src/app/page.tsx (1)

37-38: Reconsider RightSidebar placement in component tree.

The RightSidebar is placed as a child of the main content, but based on its styling (fixed positioning), it should likely be at the layout level rather than within the page content.

Consider moving the RightSidebar to the layout file (apps/web/src/app/layout.tsx) so it appears consistently across all pages, or ensure this placement is intentional for homepage-only display.

apps/web/src/components/layout/RightSidebar.tsx (1)

1-1: Remove unnecessary 'use client' directive.

The component doesn't contain any client-side interactivity (no state, effects, or event handlers), so the 'use client' directive is unnecessary and adds to the client bundle size.

-'use client';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1a484f and a7a3d70.

⛔ Files ignored due to path filters (11)
  • apps/web/public/icons/agenda.png is excluded by !**/*.png
  • apps/web/public/icons/calendar.png is excluded by !**/*.png
  • apps/web/public/icons/heart.png is excluded by !**/*.png
  • apps/web/public/icons/location.png is excluded by !**/*.png
  • apps/web/public/icons/lock.png is excluded by !**/*.png
  • apps/web/public/icons/menu.png is excluded by !**/*.png
  • apps/web/public/icons/message.png is excluded by !**/*.png
  • apps/web/public/icons/search.png is excluded by !**/*.png
  • apps/web/public/icons/send.png is excluded by !**/*.png
  • apps/web/public/icons/settings.png is excluded by !**/*.png
  • apps/web/public/logo.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • apps/web/src/app/layout.tsx (2 hunks)
  • apps/web/src/app/page.tsx (1 hunks)
  • apps/web/src/components/features/search/SearchBar.tsx (2 hunks)
  • apps/web/src/components/layout/RightSidebar.tsx (1 hunks)
  • apps/web/src/components/search/PropertyCard.tsx (1 hunks)
  • apps/web/src/components/search/PropertyGrid.tsx (1 hunks)
  • apps/web/src/components/ui/icon-container.tsx (1 hunks)
  • apps/web/tailwind.config.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
apps/web/src/app/layout.tsx (1)
apps/web/src/components/shared/layout/providers.tsx (1)
  • Providers (26-71)
apps/web/src/components/layout/RightSidebar.tsx (2)
apps/web/src/components/ui/icon-container.tsx (1)
  • IconContainer (8-16)
apps/backend/src/types/auth.types.ts (1)
  • User (9-13)
apps/web/src/components/search/PropertyCard.tsx (1)
apps/web/src/lib/types/property.ts (1)
  • PropertyCardProps (72-74)
🔇 Additional comments (3)
apps/web/src/app/layout.tsx (1)

27-27: Ensure site-wide navigation remains accessible after removing <Navbar />

I see that the persistent <Navbar /> component has been removed from
apps/web/src/app/layout.tsx (line 27), yet the pr-16 on <main> still reserves sidebar space. While there are <nav> blocks in your dashboard pages, there’s no global navigation rendered on other routes.

Please manually verify:

  • That primary site links (home, listings, profile, etc.) are reachable on every page.
  • That removing <Navbar /> hasn’t broken any next/link-based navigation.
  • Whether the pr-16 padding is still needed or should be adjusted now that the Navbar/sidebar is absent.
apps/web/src/app/page.tsx (1)

13-13: Logo asset confirmed

The referenced /logo.png exists at apps/web/public/logo.png, so no changes are needed here.

apps/web/src/components/search/PropertyGrid.tsx (1)

129-137: Component lacks error handling and loading states

The simplified component no longer handles loading states or errors. This could lead to poor user experience if data fetching is implemented later.

Consider adding:

-export const PropertyGrid = () => {
+export const PropertyGrid = () => {
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState<string | null>(null);
+
+  if (loading) return <div>Loading properties...</div>;
+  if (error) return <div>Error loading properties: {error}</div>;
+  if (mockProperties.length === 0) return <div>No properties found</div>;
+
   return (
     <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
       {mockProperties.map((property) => (
         <PropertyCard key={property.id} property={property} />
       ))}
     </div>
   );
 };

Likely an incorrect or invalid review comment.

Comment on lines +24 to +27
<span className="text-white text-sm bg-secondary p-2 px-4 rounded-full flex items-center gap-2">
<House className="w-4 h-4" />
Showing 23 properties
</span>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace hardcoded property count with dynamic value.

The property count is hardcoded as "23 properties" which will become outdated and misleading as the actual property data changes.

Consider making this dynamic by passing the actual count from the PropertyGrid or a data source:

-            Showing 23 properties
+            Showing {propertyCount} properties
📝 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
<span className="text-white text-sm bg-secondary p-2 px-4 rounded-full flex items-center gap-2">
<House className="w-4 h-4" />
Showing 23 properties
</span>
<span className="text-white text-sm bg-secondary p-2 px-4 rounded-full flex items-center gap-2">
<House className="w-4 h-4" />
Showing {propertyCount} properties
</span>
🤖 Prompt for AI Agents
In apps/web/src/app/page.tsx around lines 24 to 27, replace the hardcoded "23
properties" text with a dynamic value representing the actual number of
properties. Pass the property count as a prop from the PropertyGrid component or
fetch it from the relevant data source, then render that count inside the span
instead of the fixed number 23.

Comment on lines +28 to 32
const [formData] = useState<SearchFormData>({
location: '',
date: '',
guests: 2,
});
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

Form data is initialized but never updated

The component initializes formData with useState but provides no way to update it. The form appears to be non-functional.

You need to either:

  1. Add input fields and update handlers
  2. Remove the unused form logic if this is meant to be a static display

Example fix if inputs are needed:

-  const [formData] = useState<SearchFormData>({
+  const [formData, setFormData] = useState<SearchFormData>({
     location: '',
     date: '',
     guests: 2,
   });
+
+  const handleLocationChange = (value: string) => {
+    setFormData(prev => ({ ...prev, location: value }));
+  };
📝 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
const [formData] = useState<SearchFormData>({
location: '',
date: '',
guests: 2,
});
const [formData, setFormData] = useState<SearchFormData>({
location: '',
date: '',
guests: 2,
});
const handleLocationChange = (value: string) => {
setFormData(prev => ({ ...prev, location: value }));
};
🤖 Prompt for AI Agents
In apps/web/src/components/features/search/SearchBar.tsx around lines 28 to 32,
the formData state is initialized but never updated, making the form
non-functional. To fix this, add input fields bound to formData properties and
implement onChange handlers that update formData using the state setter function
from useState. Alternatively, if the form is meant to be static, remove the
formData state and related logic entirely.

Comment on lines +87 to 154
{/* Location Field */}
<div className="flex relative group">
<div className="flex items-center rounded-2xl p-5 gap-4">
<IconContainer
icon={
<Image
src="/icons/location.png"
alt="Location"
width={40}
height={40}
className="p-2"
/>
}
/>
</div>

{showSuggestions && suggestions.length > 0 && (
<select
id="location-listbox"
className="absolute w-full mt-1 bg-background border rounded-md shadow-md z-20 max-h-48 overflow-y-auto"
size={Math.min(suggestions.length, 5)}
onChange={(e) => selectSuggestion(e.target.value)}
onBlur={() => setShowSuggestions(false)}
>
{suggestions.map((suggestion) => (
<option
key={suggestion}
value={suggestion}
className="p-2 hover:bg-muted cursor-pointer"
>
{suggestion}
</option>
))}
</select>
)}
</div>

<div className="flex flex-1 md:flex-row gap-2">
<div className="flex flex-col gap-2 items-center border rounded-md p-2 bg-background flex-1">
<small>Check in</small>
<div className="flex items-center border rounded-md p-2 bg-background flex-1">
<Calendar className="h-5 w-5 text-muted-foreground mr-2" />
<Input
type="date"
placeholder="Check-in"
value={formData.checkIn}
onChange={(e) => {
setFormData({ ...formData, checkIn: e.target.value });
setError(null);
}}
className="border-0 p-0 focus-visible:ring-0"
aria-label="Check-in date"
min={new Date().toISOString().split("T")[0]}
/>
<div className="flex flex-col">
<p className="text-white font-semibold text-lg block">Location</p>
<p className="text-sm text-gray-400 mt-1">Search by country or city</p>
</div>
</div>
</div>

<div className="flex flex-col gap-2 items-center border rounded-md p-2 bg-background flex-1">
<small>Check out</small>
<div className="flex items-center border rounded-md p-2 bg-background flex-1">
<Calendar className="h-5 w-5 text-muted-foreground mr-2" />
<Input
type="date"
placeholder="Check-out"
value={formData.checkOut}
onChange={(e) => {
setFormData({ ...formData, checkOut: e.target.value });
setError(null);
}}
className="border-0 p-0 focus-visible:ring-0"
aria-label="Check-out date"
min={
formData.checkIn || new Date().toISOString().split("T")[0]
}
/>
<div className="w-1 h-20 bg-gray-600/30 self-center" />

{/* Date Field */}
<div className="flex relative group">
<div className="flex items-center rounded-2xl p-5 gap-4">
<IconContainer
icon={
<Image
src="/icons/calendar.png"
alt="Calendar"
width={40}
height={40}
className="p-2"
/>
}
/>
<div className="flex flex-col">
<p className="text-white font-semibold text-lg block">Date</p>
<p className="text-sm text-gray-400 mt-1">Select a date</p>
</div>
</div>
</div>

<div className="flex flex-row gap-4">
<div className="flex items-center border max-h-[70px] rounded-md p-2 bg-background">
<Users className="h-5 w-5 text-muted-foreground mr-2" />
<Input
type="number"
min="1"
max="16"
step="1"
placeholder="Guests"
value={formData.guests}
onChange={(e) => {
const value = Number.parseInt(e.target.value) || 0;
setFormData({
...formData,
guests: value
});
const fieldError = validateField("guests", value);
setError(fieldError);
}}
className="border-0 p-0 focus-visible:ring-0 w-16"
aria-label="Number of guests"
<div className="w-1 h-20 bg-gray-600/30 self-center" />

{/* Guests Field */}
<div className="flex relative group">
<div className="flex items-center rounded-2xl p-5 gap-4">
<IconContainer
icon={
<Image
src="/icons/agenda.png"
alt="Agenda"
width={40}
height={40}
className="p-2"
/>
}
/>
<div className="flex flex-col">
<p className="text-white font-semibold text-lg block">Guests</p>
<p className="text-sm text-gray-400 mt-1">2 Guests (1 Adult - 1 Kid)</p>
</div>
</div>

<Button
type="submit"
className="bg-blue-900 hover:bg-blue-800 text-white dark:bg-blue-700 dark:hover:bg-blue-600"
disabled={isSubmitting || !!error}
>
{isSubmitting ? "Searching..." : "Search"}
</Button>
</div>
</form>

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Form has no input fields or submit button

The form structure exists with submission handling, but there are no actual input elements or submit button. The UI only displays static text with icons.

This appears to be an incomplete implementation. The form cannot function without:

  1. Input fields for location, date, and guests
  2. A submit button to trigger the search

Let me check if there's a separate component or if this is intentional:


🏁 Script executed:

#!/bin/bash
# Description: Check for other search-related components or if this is a work in progress

# Look for other search components
echo "Searching for other search-related components:"
fd -e tsx -e ts "search" apps/web/src/components/ -x grep -l "input\|Input\|button\|Button" {} \;

# Check if there's a TODO or FIXME comment about this
echo -e "\nChecking for TODO/FIXME comments in search components:"
rg -i "todo|fixme|wip|work in progress" apps/web/src/components/features/search/ -A 2 -B 2

# Check the PR description or related issues
echo -e "\nChecking if this is mentioned in the homepage refactor:"
rg -i "search.*static|search.*display|search.*visual" apps/web/

Length of output: 713


Incomplete SearchBar form: missing inputs and submit button

The current <form> only renders static icons and text without any interactive input fields or a submit trigger. To complete the search functionality, please:

  • Add form controls for each field:
    • Location → <input> or custom dropdown tied to state
    • Date → <input type="date"> or date-picker component
    • Guests → number input or guest-selector component
  • Include a <button type="submit">Search</button> inside the form to invoke handleSubmit
  • Wire each control to React state (e.g. via useState or form library) so handleSubmit can read user inputs

If the intention is to use custom click-to-open pickers instead of native inputs, please either add TODO comments clarifying that work or implement the necessary click handlers and modals now.

🤖 Prompt for AI Agents
In apps/web/src/components/features/search/SearchBar.tsx between lines 87 and
154, the form currently only displays static icons and labels without any
interactive input elements or a submit button. To fix this, add appropriate form
controls for each field: a controlled input or dropdown for Location, a date
input or date-picker component for Date, and a number input or guest selector
for Guests, all wired to React state using useState or a form library. Also,
include a button with type="submit" inside the form to trigger handleSubmit. If
custom pickers are intended instead of native inputs, add TODO comments or
implement the necessary click handlers and modals now.

Comment on lines +12 to +42
<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/menu.png" alt="Menu" width={40} height={40} className="p-2" />
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<IconContainer
icon={
<Image src="/icons/search.png" alt="Search" width={40} height={40} className="p-2" />
}
/>
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/heart.png" alt="Heart" width={40} height={40} className="p-2" />
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/send.png" alt="Send" width={40} height={40} className="p-2" />
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/settings.png" alt="Settings" width={40} height={40} className="p-2" />
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/lock.png" alt="Lock" width={40} height={40} className="p-2" />
</button>

<button type="button" className="text-primary transition-colors duration-200 p-2">
<Image src="/icons/message.png" alt="Message" width={40} height={40} className="p-2" />
</button>
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify icon assets exist and add functionality to buttons.

The component has several issues:

  1. All buttons reference icon files that should be verified to exist
  2. Buttons lack onClick handlers, making them non-functional
  3. Only the search button uses IconContainer while others don't, creating visual inconsistency

For consistency, either wrap all icons with IconContainer or use a consistent styling approach:

         <button type="button" className="text-primary transition-colors duration-200 p-2">
-          <Image src="/icons/menu.png" alt="Menu" width={40} height={40} className="p-2" />
+          <IconContainer
+            icon={
+              <Image src="/icons/menu.png" alt="Menu" width={40} height={40} className="p-2" />
+            }
+          />
         </button>

Also, add onClick handlers to make the buttons functional.


🏁 Script executed:

#!/bin/bash
# Check if all referenced icon files exist
fd "menu.png" public/icons/
fd "search.png" public/icons/
fd "heart.png" public/icons/
fd "send.png" public/icons/
fd "settings.png" public/icons/
fd "lock.png" public/icons/
fd "message.png" public/icons/

Length of output: 912


🏁 Script executed:

#!/bin/bash
# Search for icon asset files across the repository
fd menu.png
fd search.png
fd heart.png
fd send.png
fd settings.png
fd lock.png
fd message.png

# Verify IconContainer component exists
rg --ignore-case "IconContainer" -n .

Length of output: 1156


Add onClick Handlers and Enforce Consistent Icon Wrapping

All referenced icons have been found under apps/web/public/icons/, and the IconContainer component exists at apps/web/src/components/ui/icon-container.tsx. However, the buttons in RightSidebar.tsx still:

  • Lack onClick handlers, rendering them non-functional.
  • Use IconContainer only for the search icon, causing an inconsistent look.

Please update apps/web/src/components/layout/RightSidebar.tsx to:

• Add appropriate onClick props to each <button>
• Wrap every <Image> in <IconContainer> (or remove the one around the search icon) for uniform styling

Example diff:

         <button
-          type="button"
+          type="button"
+          onClick={() => { /* TODO: implement handler */ }}
           className="text-primary transition-colors duration-200 p-2"
         >
-          <Image src="/icons/menu.png" alt="Menu" width={40} height={40} className="p-2" />
+          <IconContainer
+            icon={
+              <Image src="/icons/menu.png" alt="Menu" width={40} height={40} className="p-2" />
+            }
+          />
         </button>

Repeat for each icon button to ensure both functionality and consistent styling.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/web/src/components/layout/RightSidebar.tsx between lines 12 and 42, the
buttons lack onClick handlers and have inconsistent icon wrapping with
IconContainer used only for the search icon. To fix this, add appropriate
onClick props to each button to make them functional, and wrap every Image
component inside an IconContainer for consistent styling across all buttons.
Ensure the onClick handlers are meaningful for each button's purpose and update
the JSX accordingly to maintain uniformity.

Comment on lines +36 to +41
<div className="absolute top-3 right-3 bg-green-500/50 text-white px-3 py-1.5 rounded-full text-xs font-semibold flex items-center gap-1.5 shadow-lg">
<Star className="w-3.5 h-3.5" />
Verificado
</div>
)}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid hardcoded text for internationalization

The "Verificado" text is hardcoded in Spanish, which breaks internationalization support.

Use a translation system or at least make it configurable:

-            Verificado
+            Verified

Or better yet, use a translation key if you have i18n setup:

+import { useTranslation } from 'next-i18next';
+
+export const PropertyCard = ({ property }: PropertyCardProps) => {
+  const { t } = useTranslation();
   // ...
-            Verificado
+            {t('property.verified')}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/web/src/components/search/PropertyCard.tsx around lines 36 to 41, the
text "Verificado" is hardcoded in Spanish, which breaks internationalization
support. Replace this hardcoded string with a translation key using the existing
i18n system or a translation function, so the text can be dynamically translated
based on the user's locale. Ensure the translation key corresponds to the
verified label in your translation files.

Comment on lines +77 to +81
<button type="button" className="bg-primary rounded-full p-2 border text-black">
<ArrowRight className="w-5 h-5" />
</button>
</Link>
</div>
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

Improve button accessibility

The button inside a Link creates nested interactive elements, which is an accessibility anti-pattern. Screen readers may have difficulty interpreting this structure.

Refactor to use either a Link or a button, not both:

-          <Link href={`/property/${property.id}`}>
-            <button type="button" className="bg-primary rounded-full p-2 border text-black">
-              <ArrowRight className="w-5 h-5" />
-            </button>
-          </Link>
+          <Link 
+            href={`/property/${property.id}`}
+            className="bg-primary rounded-full p-2 border text-black inline-flex items-center justify-center hover:opacity-80 transition-opacity"
+            aria-label={`View details for ${property.title}`}
+          >
+            <ArrowRight className="w-5 h-5" />
+          </Link>
📝 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
<Link href={`/property/${property.id}`}>
<button type="button" className="bg-primary rounded-full p-2 border text-black">
<ArrowRight className="w-5 h-5" />
</button>
</Link>
<Link
href={`/property/${property.id}`}
className="bg-primary rounded-full p-2 border text-black inline-flex items-center justify-center hover:opacity-80 transition-opacity"
aria-label={`View details for ${property.title}`}
>
<ArrowRight className="w-5 h-5" />
</Link>
🤖 Prompt for AI Agents
In apps/web/src/components/search/PropertyCard.tsx around lines 77 to 81, the
current code nests a button inside a Link, causing accessibility issues due to
nested interactive elements. Refactor by removing the button element and instead
apply the button styles directly to the Link component, ensuring it behaves like
a button but remains a single interactive element. This will improve screen
reader compatibility and maintain the intended styling and functionality.

Comment on lines +5 to +127
// Mock data for properties
const mockProperties = [
{
id: 1,
title: 'Luxury Studio in SoHo',
address: '158 Greene St, New York, NY',
image: '/images/house1.jpg',
maxPeople: 2,
distance: 0.8,
rating: 4.8,
reviews: 114,
area: 40,
price: 3200,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 2,
title: 'Modern Loft in Downtown',
address: '1122 S Main St, Los Angeles, CA',
image: '/images/house2.jpg',
maxPeople: 2,
distance: 1.5,
rating: 4.6,
reviews: 54,
area: 55,
price: 2800,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 3,
title: 'Penthouse in Brickell',
address: '950 Brickell Bay Dr, Miami, FL',
image: '/images/house3.jpg',
maxPeople: 4,
distance: 2.0,
rating: 4.9,
reviews: 84,
area: 100,
price: 5100,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 4,
title: 'Cozy Condo near Pike Place',
address: '1410 2nd Ave, Seattle, WA',
image: '/images/house4.jpg',
maxPeople: 2,
distance: 1.8,
rating: 4.2,
reviews: 162,
area: 50,
price: 2950,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 5,
title: 'Designer Apartment',
address: '1234 Design St, San Francisco, CA',
image: '/images/house5.jpg',
maxPeople: 3,
distance: 1.2,
rating: 4.7,
reviews: 89,
area: 65,
price: 3800,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 6,
title: 'Waterfront Home in Santa Monica',
address: '567 Ocean Blvd, Santa Monica, CA',
image: '/images/house.jpg',
maxPeople: 6,
distance: 0.5,
rating: 4.9,
reviews: 203,
area: 120,
price: 7500,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 7,
title: 'High-Rise in The Loop',
address: '789 Michigan Ave, Chicago, IL',
image: '/images/house1.jpg',
maxPeople: 2,
distance: 1.1,
rating: 4.5,
reviews: 76,
area: 45,
price: 2600,
currency: 'USD',
period: 'per month',
verified: true,
},
{
id: 8,
title: 'Smart Home in Austin',
address: '321 Tech Blvd, Austin, TX',
image: '/images/house2.jpg',
maxPeople: 4,
distance: 2.3,
rating: 4.8,
reviews: 95,
area: 85,
price: 4200,
currency: 'USD',
period: 'per month',
verified: true,
},
];
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Replace hardcoded mock data with proper data fetching

The component now uses hardcoded mock data instead of accepting props. While this might be acceptable for initial UI development, it removes the component's reusability and dynamic data capabilities.

Consider:

  1. Fetching data from an API or database
  2. Implementing proper loading and error states
  3. Re-adding pagination or infinite scroll for better performance with large datasets

Let me verify if the referenced image paths exist:


🏁 Script executed:

#!/bin/bash
# Description: Check if the mock data image paths exist in the public directory

# Search for the image files referenced in the mock data
echo "Checking for image files referenced in mock data:"
fd -e jpg -e png "house" public/images/ || echo "No image files found in public/images/"

# List all files in public/images if the directory exists
if [ -d "public/images" ]; then
    echo -e "\nAll files in public/images:"
    ls -la public/images/
else
    echo "public/images directory does not exist"
fi

Length of output: 451


Replace mock data with dynamic fetching & correct image assets

The PropertyGrid.tsx component currently uses hardcoded mockProperties and references image paths under /images/house*.jpg, but our verification shows the public/images/ directory (and thus those assets) does not exist. This will lead to broken images and makes the component non-reusable.

Please address the following in apps/web/src/components/search/PropertyGrid.tsx:

  • Replace mockProperties with data passed in via props or fetched from your API.
  • Add loading and error states around asynchronous data fetching.
  • Re-introduce pagination or infinite scroll to handle large data sets efficiently.
  • Correct the image references:
    • Ensure the /public/images/house*.jpg assets are added, or
    • Point to existing image URLs, or
    • Provide a fallback placeholder if an image fails to load.
🤖 Prompt for AI Agents
In apps/web/src/components/search/PropertyGrid.tsx from lines 5 to 127, replace
the hardcoded mockProperties array with dynamic data fetching or accept property
data via props. Implement loading and error states to handle asynchronous data
retrieval gracefully. Add pagination or infinite scroll to efficiently manage
large datasets. For images, either add the missing /public/images/house*.jpg
assets, update image URLs to valid existing sources, or implement a fallback
placeholder image to avoid broken image links.

Comment on lines +8 to +16
export const IconContainer = ({ icon, className = '' }: IconContainerProps) => {
return (
<div
className={`w-12 flex items-center justify-center h-12 rounded-2xl bg-opacity-20 shadow-[inset_0_2px_10px_0_rgba(98,145,212,0.2),inset_0_2px_1px_0_rgba(66,135,232,0.2)] ${className}`}
>
{icon}
</div>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix background opacity and consider design system consistency.

The component has two potential issues:

  1. bg-opacity-20 is applied without a background color, which won't have any visual effect
  2. The hardcoded RGBA values in the shadow might not align with your design system

Consider this improvement:

-      className={`w-12 flex items-center justify-center h-12 rounded-2xl bg-opacity-20 shadow-[inset_0_2px_10px_0_rgba(98,145,212,0.2),inset_0_2px_1px_0_rgba(66,135,232,0.2)] ${className}`}
+      className={`w-12 flex items-center justify-center h-12 rounded-2xl bg-primary/20 shadow-[inset_0_2px_10px_0_rgba(98,145,212,0.2),inset_0_2px_1px_0_rgba(66,135,232,0.2)] ${className}`}

Or better yet, use Tailwind's design tokens for the shadow values if available in your design system.

📝 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
export const IconContainer = ({ icon, className = '' }: IconContainerProps) => {
return (
<div
className={`w-12 flex items-center justify-center h-12 rounded-2xl bg-opacity-20 shadow-[inset_0_2px_10px_0_rgba(98,145,212,0.2),inset_0_2px_1px_0_rgba(66,135,232,0.2)] ${className}`}
>
{icon}
</div>
);
};
export const IconContainer = ({ icon, className = '' }: IconContainerProps) => {
return (
<div
className={`w-12 flex items-center justify-center h-12 rounded-2xl bg-primary/20 shadow-[inset_0_2px_10px_0_rgba(98,145,212,0.2),inset_0_2px_1px_0_rgba(66,135,232,0.2)] ${className}`}
>
{icon}
</div>
);
};
🤖 Prompt for AI Agents
In apps/web/src/components/ui/icon-container.tsx around lines 8 to 16, the
IconContainer component applies bg-opacity-20 without a background color, so the
opacity has no effect, and it uses hardcoded RGBA values for shadows that may
not match the design system. To fix this, add a background color class from the
design system (e.g., bg-primary or bg-blue-500) to make the opacity effective,
and replace the hardcoded shadow RGBA values with Tailwind design tokens or
variables consistent with your design system's color palette.

DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
secondary: '#0E1827',
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Maintain consistency with other color definitions.

The secondary color is now defined as a static hex value while all other colors use the HSL with CSS variables pattern. This breaks the theming system's consistency and could prevent proper theme switching functionality.

Consider maintaining the same pattern as other colors:

-        secondary: '#0E1827',
+        secondary: {
+          DEFAULT: 'hsl(var(--secondary))',
+          foreground: 'hsl(var(--secondary-foreground))',
+        },

Then define the corresponding CSS variables in your global CSS file.

📝 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
secondary: '#0E1827',
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
🤖 Prompt for AI Agents
In apps/web/tailwind.config.js at line 34, the secondary color is defined as a
static hex value, which breaks consistency with other colors using HSL and CSS
variables. Change the secondary color definition to use the HSL with CSS
variables pattern like the others, and ensure the corresponding CSS variables
are defined in the global CSS file to maintain proper theming and theme
switching functionality.

@respp
Copy link
Contributor

respp commented Jul 26, 2025

LGTM, thanks for your contribution!!

@respp respp merged commit 8aeb435 into Stellar-Rent:main Jul 26, 2025
6 of 8 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 10, 2025
4 tasks
@coderabbitai coderabbitai bot mentioned this pull request Jan 30, 2026
4 tasks
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.

Update homepage

2 participants