-
Notifications
You must be signed in to change notification settings - Fork 76
fix: lint errors #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: lint errors #54
Changes from all commits
456b2e2
c51785e
ba80157
d679ffd
de15a53
7438f75
f1c847a
5fd7e7a
5830524
fc6efe6
63a12bf
5a24a0f
1f39b48
e028137
97c018f
e994269
308e01f
bbe25bd
485361a
84e47e1
87d9866
c37a234
25c949d
9080ca4
d38811a
478cb89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,39 @@ | ||
| import Image from 'next/image'; | ||
| import { FeaturedProperties } from '@/components/features/properties/FeaturedProperties'; | ||
| import { SearchBar } from '@/components/features/search/SearchBar'; | ||
| import { HowItWorks } from '@/components/shared/HowItWorks'; | ||
| import { Testimonials } from '@/components/shared/Testimonials'; | ||
| import { Footer } from '@/components/shared/layout/Footer'; | ||
| import { HeroSection } from '@/components/shared/layout/HeroSection'; | ||
| import { Suspense } from 'react'; | ||
|
|
||
| export default function Home() { | ||
| const mensaje = 'Hola Mundo'; | ||
| const fecha = new Date().toLocaleDateString(); | ||
|
|
||
| return ( | ||
| <main className="flex flex-1 flex-col items-center justify-between p-8"> | ||
| <h1>{mensaje}</h1> | ||
| <p>Fecha: {fecha}</p> | ||
| <main className="flex flex-1 flex-col w-full"> | ||
| {/* Hero Section */} | ||
| <section id="hero" className="relative"> | ||
| <HeroSection /> | ||
| <div className="relative z-10"> | ||
| <SearchBar /> | ||
| </div> | ||
| </section> | ||
|
|
||
| {/* Featured Properties Section */} | ||
| <Suspense fallback={<div className="py-16 text-center">Loading properties...</div>}> | ||
| <FeaturedProperties /> | ||
| </Suspense> | ||
|
|
||
| {/* How It Works Section */} | ||
| <section id="how-it-works"> | ||
| <HowItWorks /> | ||
| </section> | ||
|
|
||
| {/* Testimonials Section */} | ||
| <section id="testimonials"> | ||
| <Testimonials /> | ||
| </section> | ||
|
|
||
| {/* Footer */} | ||
| <Footer /> | ||
| </main> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import type { Metadata } from 'next'; | ||
| import PropertyDetail from '@/components/features/properties/PropertyDetail'; | ||
|
|
||
| // This would typically come from an API | ||
| const getPropertyById = async (id: string) => { | ||
| // In a real app, this would be an API call | ||
| // For now, we're mocking it and leveraging the component's built-in data | ||
| return { id }; | ||
| }; | ||
|
|
||
| type Props = { | ||
| params: { id: string }; | ||
| }; | ||
|
|
||
| export async function generateMetadata({ params }: Props): Promise<Metadata> { | ||
| // Fetch property details to use in metadata | ||
| // In a real app, this would come from an API | ||
| return { | ||
| title: `Property ${params.id} | StellarRent`, | ||
| description: `View details and book property ${params.id} with cryptocurrency on StellarRent.`, | ||
| }; | ||
| } | ||
|
|
||
| export default async function PropertyPage({ params }: Props) { | ||
| const { id } = params; | ||
|
|
||
| // In a real app, this would fetch property data from an API | ||
| // and pass it to the PropertyDetail component | ||
| await getPropertyById(id); | ||
|
|
||
| return <PropertyDetail id={id} />; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| 'use client'; | ||
|
|
||
| import { Button } from '@/components/ui/button'; | ||
| import { Card } from '@/components/ui/card'; | ||
| import { cn } from '@/lib/utils'; | ||
| import { Heart, MapPin, Star } from 'lucide-react'; | ||
| import Image from 'next/image'; | ||
| import Link from 'next/link'; | ||
| import { Suspense, useState } from 'react'; | ||
| import { useInView } from 'react-intersection-observer'; | ||
|
|
||
| // Types | ||
| type Property = { | ||
| id: string; | ||
| title: string; | ||
| location: string; | ||
| price: number; | ||
| image: string; | ||
| rating: number; | ||
| distance: string; | ||
| }; | ||
|
|
||
| // Mock data for properties | ||
| const MOCK_PROPERTIES: Property[] = [ | ||
| { | ||
| id: '1', | ||
| title: 'Modern Apartment with Kitchen', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 2500, | ||
| image: '/images/house1.jpg', | ||
| rating: 4.1, | ||
| distance: '30km', | ||
| }, | ||
| { | ||
| id: '2', | ||
| title: 'Luxury Villa with Pool', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 6000, | ||
| image: '/images/house2.jpg', | ||
| rating: 4.8, | ||
| distance: '6km', | ||
| }, | ||
| { | ||
| id: '3', | ||
| title: 'Cozy Bedroom Suite', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 4500, | ||
| image: '/images/house3.jpg', | ||
| rating: 3.9, | ||
| distance: '14km', | ||
| }, | ||
| { | ||
| id: '4', | ||
| title: 'Elegant Studio Apartment', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 5600, | ||
| image: '/images/house4.jpg', | ||
| rating: 4.5, | ||
| distance: '8km', | ||
| }, | ||
| { | ||
| id: '5', | ||
| title: 'Charming Kitchen Loft', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 2100, | ||
| image: '/images/house5.jpg', | ||
| rating: 4.2, | ||
| distance: '12km', | ||
| }, | ||
| { | ||
| id: '6', | ||
| title: 'Modern Architectural House', | ||
| location: 'Luján, Buenos Aires', | ||
| price: 6500, | ||
| image: '/images/house.jpg', | ||
| rating: 4.7, | ||
| distance: '10km', | ||
| }, | ||
| ]; | ||
|
|
||
| // Property Card Component | ||
| const PropertyCard = ({ property }: { property: Property }) => { | ||
| // Use IntersectionObserver to detect when the card comes into view | ||
| const { ref, inView } = useInView({ | ||
| triggerOnce: true, | ||
| threshold: 0.1, | ||
| }); | ||
|
|
||
| return ( | ||
| <div | ||
| ref={ref} | ||
| className={`transition-opacity duration-500 ${inView ? 'opacity-100' : 'opacity-0'}`} | ||
| > | ||
| <Card className="overflow-hidden h-full"> | ||
| <div className="relative h-48 w-full"> | ||
| <div className="absolute top-2 left-2 z-10 bg-white/90 dark:bg-[#0B1D39]/90 px-2 py-1 rounded-md text-sm font-medium"> | ||
| ${property.price} <span className="text-xs">USDC</span> | ||
| </div> | ||
| <div className="absolute top-2 right-2 z-10"> | ||
| <Button | ||
| variant="ghost" | ||
| size="icon" | ||
| className="rounded-full bg-white/30 hover:bg-white/50 text-white" | ||
| > | ||
| <Heart className="w-5 h-5" /> | ||
| </Button> | ||
| </div> | ||
| <div className="absolute bottom-2 left-2 z-10 bg-white/90 dark:bg-[#0B1D39]/90 px-2 py-1 rounded-md text-xs font-medium flex items-center"> | ||
| <MapPin className="w-3 h-3 mr-1" /> {property.distance} | ||
| </div> | ||
| <div className="absolute bottom-2 right-2 z-10 bg-white/90 dark:bg-[#0B1D39]/90 px-2 py-1 rounded-md text-xs font-medium flex items-center"> | ||
| <Star className="w-3 h-3 mr-1 text-yellow-500" /> {property.rating} | ||
| </div> | ||
| {/* Fallback image with linear gradient if actual image fails to load */} | ||
| <div className="relative h-full w-full"> | ||
| <Image | ||
| src={property.image} | ||
| alt={property.title} | ||
| fill | ||
| className="object-cover" | ||
| sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" | ||
| /> | ||
| </div> | ||
| </div> | ||
| <div className="p-4"> | ||
| <h3 className="font-semibold text-lg mb-1 line-clamp-1">{property.title}</h3> | ||
| <p className="text-muted-foreground text-sm mb-3 flex items-center"> | ||
| <MapPin className="w-4 h-4 mr-1" /> {property.location} | ||
| </p> | ||
| <Button asChild className="w-full"> | ||
| <Link href={`/property/${property.id}`}>View Details</Link> | ||
| </Button> | ||
|
Comment on lines
+130
to
+132
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify property detail routes exist. The component links to Please verify that the property detail routes are implemented: 🏁 Script executed: #!/bin/bash
# Check for property detail page implementation
echo "Checking for property detail route implementation..."
# Look for dynamic property routes
fd -t f "\\[.*\\]" apps/web/src/app/ | grep -i property || echo "No dynamic property routes found"
# Look for property-related page files
fd -t f "page.tsx" apps/web/src/app/ | xargs grep -l "property" 2>/dev/null || echo "No property-related pages found"
# Check for property detail components
rg -l "PropertyDetail|PropertyPage" apps/web/src/components/ || echo "No property detail components found"Length of output: 524 Property detail route is missing I ran a search and found no implementation for the
For example: // apps/web/src/app/property/[id]/page.tsx
import { GetPropertyById } from 'lib/api'
import PropertyDetail from 'src/components/features/properties/PropertyDetail'
export default async function PropertyPage({ params: { id } }) {
const property = await GetPropertyById(id)
return <PropertyDetail property={property} />
}🤖 Prompt for AI Agents |
||
| </div> | ||
| </Card> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| // Fallback loading component | ||
| const PropertyCardSkeleton = () => ( | ||
| <Card className="overflow-hidden h-full"> | ||
| <div className="h-48 w-full bg-muted animate-pulse" /> | ||
| <div className="p-4"> | ||
| <div className="h-6 bg-muted animate-pulse rounded mb-2" /> | ||
| <div className="h-4 bg-muted animate-pulse rounded mb-4 w-3/4" /> | ||
| <div className="h-10 bg-muted animate-pulse rounded" /> | ||
| </div> | ||
| </Card> | ||
| ); | ||
|
|
||
| // Main component | ||
| export const FeaturedProperties = () => { | ||
| return ( | ||
| <section className="py-16 bg-gradient-to-b from-white to-blue-50 dark:from-[#0B1D39] dark:to-[#071429]"> | ||
| <div className="container mx-auto px-4"> | ||
| <div className="flex flex-col items-center mb-12 text-center"> | ||
| <h2 className="text-3xl md:text-4xl font-bold mb-4">Featured Properties</h2> | ||
| <p className="text-muted-foreground max-w-2xl"> | ||
| Discover our handpicked selection of premium properties available for rent with | ||
| cryptocurrency. | ||
| </p> | ||
| </div> | ||
|
|
||
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | ||
| {MOCK_PROPERTIES.map((property) => ( | ||
| <PropertyCard key={property.id} property={property} /> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| </section> | ||
| ); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove redundant mock function that creates confusion.
The
getPropertyByIdfunction here only returns{ id }, but thePropertyDetailcomponent calls its owngetPropertyByIdfunction expecting full property data. This creates redundant data fetching and architectural confusion.Apply this diff to simplify the implementation:
And update the component:
export default async function PropertyPage({ params }: Props) { const { id } = params; - // In a real app, this would fetch property data from an API - // and pass it to the PropertyDetail component - await getPropertyById(id); - return <PropertyDetail id={id} />; }📝 Committable suggestion
🤖 Prompt for AI Agents