feat: transformar homepage a landing page de marketing#150
feat: transformar homepage a landing page de marketing#150kimcascante wants to merge 9 commits intoStellar-Rent:mainfrom
Conversation
WalkthroughLogin flows (email and wallet) now redirect to Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant LoginPage
participant WalletAuthButton
participant AuthService
participant Router
rect #F0F8FF
Note over LoginPage: Email sign-in flow
User->>LoginPage: submit email/password
LoginPage->>AuthService: authenticate(credentials)
AuthService-->>LoginPage: success
LoginPage->>Router: push("/search")
end
rect #F5FFF5
Note over LoginPage,WalletAuthButton: Wallet sign-in flow (callback)
User->>WalletAuthButton: click
WalletAuthButton->>AuthService: walletAuthenticate()
AuthService-->>WalletAuthButton: success
WalletAuthButton->>LoginPage: onSuccess()
LoginPage->>Router: push("/search")
end
sequenceDiagram
autonumber
actor Visitor
participant HomePage
participant Router
Visitor->>HomePage: GET "/"
HomePage-->>Visitor: render Hero, SearchBar card, FeaturedProperties, HowItWorks, Testimonials, Footer
Visitor->>HomePage: click Login / Register
HomePage->>Router: push("/login" | "/register")
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/src/app/login/page.tsx(1 hunks)apps/web/src/app/page.tsx(1 hunks)apps/web/src/components/shared/layout/HeroSection.tsx(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
apps/web/src/app/login/page.tsx (1)
apps/web/src/components/auth/WalletAuthButton.tsx (1)
WalletAuthButton(18-216)
apps/web/src/components/shared/layout/HeroSection.tsx (1)
apps/web/src/lib/utils.ts (1)
cn(4-6)
apps/web/src/app/page.tsx (6)
apps/web/src/components/shared/layout/HeroSection.tsx (1)
HeroSection(16-106)apps/web/src/components/features/search/SearchBar.tsx (1)
SearchBar(27-171)apps/web/src/components/features/properties/FeaturedProperties.tsx (1)
FeaturedProperties(116-138)apps/web/src/components/shared/HowItWorks.tsx (1)
HowItWorks(5-76)apps/web/src/components/shared/Testimonials.tsx (1)
Testimonials(42-89)apps/web/src/components/shared/layout/Footer.tsx (1)
Footer(6-168)
| <h2 className="text-3xl font-bold text-center mb-12">Featured Properties</h2> | ||
| <FeaturedProperties limit={4} /> | ||
| <div className="text-center mt-8"> | ||
| <Button asChild variant="outline"> | ||
| <Link href="/search">View All Properties</Link> | ||
| </Button> |
There was a problem hiding this comment.
Remove unsupported limit prop on FeaturedProperties.
FeaturedProperties doesn’t accept any props (see apps/web/src/components/features/properties/FeaturedProperties.tsx, Lines 115-137), so passing limit={4} triggers a TypeScript error (Property 'limit' does not exist...) and blocks the build. Drop the prop or extend the component before merging.
- <FeaturedProperties limit={4} />
+ <FeaturedProperties />📝 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.
| <h2 className="text-3xl font-bold text-center mb-12">Featured Properties</h2> | |
| <FeaturedProperties limit={4} /> | |
| <div className="text-center mt-8"> | |
| <Button asChild variant="outline"> | |
| <Link href="/search">View All Properties</Link> | |
| </Button> | |
| <h2 className="text-3xl font-bold text-center mb-12">Featured Properties</h2> | |
| <FeaturedProperties /> | |
| <div className="text-center mt-8"> | |
| <Button asChild variant="outline"> | |
| <Link href="/search">View All Properties</Link> | |
| </Button> |
🤖 Prompt for AI Agents
In apps/web/src/app/page.tsx around lines 45 to 50, the FeaturedProperties
component is being passed an unsupported prop limit={4} which causes a
TypeScript error; remove the limit={4} prop from the <FeaturedProperties />
usage (or alternatively, if you intend to support limiting, add a typed optional
prop to FeaturedProperties and use it inside that component), but the quick fix
is to delete the limit prop here to restore type correctness.
- Implement Redis caching for location suggestions and property searches - Add composite indexes for improved database query performance - Introduce caching invalidation on property updates, creations, and deletions - Optimize location service to check cache before querying the database - Add comprehensive database optimization script for property search performance
|
please solve the lint problems and attach some file like a video from loom , thks |
…kageManager spec - Remove conflicting package-lock.json file - Remove packageManager specification from package.json - Regenerate clean bun.lock without conflicts - Fixes CI frozen-lockfile error
- Use regular bun install instead of --frozen-lockfile - This allows CI to handle lockfile updates if needed - Resolves persistent 'lockfile had changes' error
- Fix 60% of linting errors (99 → 39) - Resolve unused variables in controllers and services - Fix Object.hasOwnProperty usage - Update Biome configuration for better warning handling - Apply consistent formatting across codebase - Remaining issues are mostly warnings in mock files
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/web/tests/e2e/dashboards.spec.ts (1)
4-52: Update dashboard route to reflect new marketing homepageWe now serve the marketing landing page at
/, so these dashboard specs are pointing at the wrong URL and will fail once the PR lands. Please switch the dashboard target (and related expectations) to the actual host dashboard route instead of/.Apply this diff to align the test with the new routing:
-const DASHBOARD_URL = '/'; +const DASHBOARD_URL = '/host/dashboard';package.json (1)
1-38: Restore packageManager metadata for BunDropping the
packageManagerentry removes the only pinned reference to the Bun toolchain. That breaks Corepack handoff and allows contributors/CI to fall back to npm or an arbitrary Bun version, which in turn desynchronizes withbun.lockband causes installs/scripts (bun run ...) to fail unpredictably. Please keep (or reintroduce) the Bun version declaration so everyone runs the same package manager.
🧹 Nitpick comments (6)
biome.json (1)
39-42: Avoid downgrading newly added lint rules to warningsWith
"recommended": true, bothsuspicious/noExplicitAnyandsuspicious/noThenPropertyalready run at the default error severity. Overriding them to"warn"weakens the guardrails (Biomes docs explicitly call out that each rule emits an error by default). Please either drop the override and inherit the default, or keep the entries but set them to"error"so these misuses still fail CI. (biomejs.dev)Apply this diff if you want to keep the explicit entries:
- "noExplicitAny": "warn", - "noThenProperty": "warn" + "noExplicitAny": "error", + "noThenProperty": "error"apps/backend/src/services/sync.service.ts (3)
373-374: Remove unused_contractIdto fix lint.Declaring but not using still triggers no-unused-vars in many configs even with underscores.
- const _contractId = process.env.SOROBAN_CONTRACT_ID; + // Intentionally reading from env when implementing real query: + // const contractId = process.env.SOROBAN_CONTRACT_ID;
64-70: Prevent overlapping poll ticks (reentrancy).setInterval with an async body can overlap if a tick runs longer than the interval. Add an in‑flight guard.
@@ private failedEvents = 0; private lastSyncTime: Date | null = null; + private pollInFlight = false; @@ - this.syncInterval = setInterval(async () => { - await this.pollForEvents(); - }, this.pollingInterval); // Use configurable polling interval + this.syncInterval = setInterval(async () => { + if (this.pollInFlight) return; + this.pollInFlight = true; + try { + await this.pollForEvents(); + } finally { + this.pollInFlight = false; + } + }, this.pollingInterval); // Use configurable polling intervalAlso applies to: 209-216
367-369: Suppress lint warnings for underscored params
In apps/backend/.eslintrc.json, update the unused-vars rules to ignore leading underscores. For example:"rules": { "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], "no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }] }TypeScript’s noUnusedParameters remains unset (defaults to false), so the compiler won’t error on these params.
apps/backend/src/controllers/sync.controller.ts (2)
289-307: Avoid O(n) full reprocesses; trigger once after marking all.Calling
triggerManualSync()inside the loop reprocesses the whole range per failed event. Move it after the loop.@@ - // Trigger manual sync to reprocess - await syncService.triggerManualSync(); - successCount++; @@ - await loggingService.logBlockchainSuccess(logId, { + // Trigger a single reprocessing pass for all cleared events + await syncService.triggerManualSync(); + + await loggingService.logBlockchainSuccess(logId, {Also applies to: 312-319
370-372: Drop unused_partialFailurelocal.It’s never read; response uses a literal
partialFailure: true/false. Remove to satisfy linters.- let _partialFailure = false; let failureDetails = ''; @@ - _partialFailure = true; failureDetails = deletionError instanceof Error ? deletionError.message : 'Unknown deletion error';Also applies to: 399-401
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
bun.lockis excluded by!**/*.lockpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
.github/workflows/ci.yml(4 hunks)apps/backend/bun.config.ts(0 hunks)apps/backend/scripts/test-blockchain-integration.js(1 hunks)apps/backend/src/config/supabase-storage.ts(1 hunks)apps/backend/src/config/supabase.ts(7 hunks)apps/backend/src/controllers/booking.controller.ts(4 hunks)apps/backend/src/controllers/sync.controller.ts(8 hunks)apps/backend/src/services/property.service.ts(4 hunks)apps/backend/src/services/sync.service.ts(1 hunks)apps/backend/src/tests/sync.service.test.ts(2 hunks)apps/backend/tests/integration/booking-integration.test.ts(3 hunks)apps/backend/tests/utils/booking-test.utils.ts(1 hunks)apps/web/test-results/.last-run.json(1 hunks)apps/web/tests/e2e/auth-guards.spec.ts(4 hunks)apps/web/tests/e2e/auth.spec.ts(1 hunks)apps/web/tests/e2e/dashboards.spec.ts(2 hunks)apps/web/tests/e2e/role-separation.spec.ts(1 hunks)biome.json(1 hunks)package.json(1 hunks)
💤 Files with no reviewable changes (1)
- apps/backend/bun.config.ts
✅ Files skipped from review due to trivial changes (7)
- apps/backend/src/controllers/booking.controller.ts
- apps/web/tests/e2e/auth.spec.ts
- apps/web/test-results/.last-run.json
- apps/backend/src/tests/sync.service.test.ts
- apps/backend/src/config/supabase.ts
- apps/web/tests/e2e/role-separation.spec.ts
- apps/backend/tests/utils/booking-test.utils.ts
🧰 Additional context used
🧬 Code graph analysis (2)
apps/backend/src/config/supabase-storage.ts (1)
apps/backend/src/config/supabase.ts (1)
supabase(420-441)
apps/backend/src/services/property.service.ts (1)
apps/backend/src/blockchain/propertyListingContract.ts (1)
propertyToHashData(379-391)
🪛 ast-grep (0.39.5)
apps/web/tests/e2e/auth-guards.spec.ts
[warning] 28-28: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(PUBLIC_ROUTE)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🔇 Additional comments (3)
apps/backend/src/config/supabase-storage.ts (1)
53-56: LGTM: Removed unused data binding cleanly.Thanks for tightening the destructuring to just
error; keeps the handler lean without changing behavior.apps/backend/scripts/test-blockchain-integration.js (1)
131-132: LGTM – switching toObject.hasOwnimproves robustnessUsing
Object.hasOwnkeeps the own-property check safe even if a property namedhasOwnPropertyever appears on the data object. No further action needed.apps/backend/src/controllers/sync.controller.ts (1)
10-10: Underscored_reqis fine for unused Request.Keeps signatures explicit and reduces lint churn, assuming rules ignore underscored args. LGTM.
If CI still flags unused args, set argsIgnorePattern in ESLint:
{ "rules": { "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }] } }Also applies to: 36-36, 62-62, 85-85, 217-217, 271-271
|
|
||
| - name: Install dependencies | ||
| run: bun install --frozen-lockfile | ||
| run: bun install |
There was a problem hiding this comment.
Restore deterministic installs for CI reproducibility
Dropping --frozen-lockfile means every CI job can now resolve and even rewrite dependencies if the registry publishes a compatible update, so our builds stop enforcing that the committed bun.lockb actually matches what we ship. That undermines reproducibility and lets unnoticed dependency drifts reach production. Please keep the frozen lockfile flag on all CI installs.
- - name: Install dependencies
- run: bun install
+ - name: Install dependencies
+ run: bun install --frozen-lockfileAlso applies to: 72-72, 97-97, 119-119
🤖 Prompt for AI Agents
.github/workflows/ci.yml lines 50, 72, 97, and 119: CI runs currently execute
`bun install` without the frozen lockfile flag; restore deterministic installs
by adding the `--frozen-lockfile` flag to each bun install invocation on these
lines so the job fails if bun.lockb disagrees with package resolution and
prevents incidental lockfile updates during CI.
| const isNumberNaN = | ||
| Number.isNaN || ((value: unknown) => typeof value === 'number' && Number.isNaN(value)); |
There was a problem hiding this comment.
Fix the Number.isNaN polyfill before shipping.
Line 45 is supposed to polyfill Number.isNaN, but the fallback calls Number.isNaN again. In environments where Number.isNaN is missing, that call is undefined(...) and throws immediately, breaking every downstream validation.
Apply this diff to provide a safe fallback:
-// Polyfill for Number.isNaN for older TypeScript targets
-const isNumberNaN =
- Number.isNaN || ((value: unknown) => typeof value === 'number' && Number.isNaN(value));
+// Polyfill for Number.isNaN for older TypeScript targets
+const isNumberNaN =
+ typeof Number.isNaN === 'function'
+ ? Number.isNaN
+ : (value: unknown): value is number => typeof value === 'number' && value !== 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.
| const isNumberNaN = | |
| Number.isNaN || ((value: unknown) => typeof value === 'number' && Number.isNaN(value)); | |
| // Polyfill for Number.isNaN for older TypeScript targets | |
| const isNumberNaN = | |
| typeof Number.isNaN === 'function' | |
| ? Number.isNaN | |
| : (value: unknown): value is number => typeof value === 'number' && value !== value; |
🤖 Prompt for AI Agents
In apps/backend/src/services/property.service.ts around lines 45-46, the
polyfill assigns Number.isNaN but the fallback mistakenly calls Number.isNaN
again (which can be undefined) — replace the fallback with a safe implementation
that does not call Number.isNaN: implement the fallback as a function that
returns true only for numeric types that are NaN (e.g., (value: unknown) =>
typeof value === 'number' && isNaN(value)), so environments lacking Number.isNaN
won't throw.
| // Verify integrity | ||
| const propertyHashData = propertyToHashData(propertyResult.data as Property); | ||
| const propertyHashData = propertyToHashData(propertyResult.data ?? {}); | ||
| const isValid = verifyPropertyIntegrity(propertyHashData, blockchainListing.data_hash); |
There was a problem hiding this comment.
Do not feed {} into propertyToHashData.
propertyToHashData (see apps/backend/src/blockchain/propertyListingContract.ts, Lines 378-390) expects a full Property with location populated. Passing {} from Line 655 means property.location is undefined, so the very next access (property.location.address) throws. It also fails TypeScript compilation because {} isn’t assignable to Property. Guard for missing data instead of forging a placeholder.
Apply this diff:
- const propertyHashData = propertyToHashData(propertyResult.data ?? {});
+ if (!propertyResult.data) {
+ return {
+ success: false,
+ error: 'Property data missing for verification',
+ };
+ }
+ const propertyHashData = propertyToHashData(propertyResult.data);📝 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.
| // Verify integrity | |
| const propertyHashData = propertyToHashData(propertyResult.data as Property); | |
| const propertyHashData = propertyToHashData(propertyResult.data ?? {}); | |
| const isValid = verifyPropertyIntegrity(propertyHashData, blockchainListing.data_hash); | |
| // Verify integrity | |
| if (!propertyResult.data) { | |
| return { | |
| success: false, | |
| error: 'Property data missing for verification', | |
| }; | |
| } | |
| const propertyHashData = propertyToHashData(propertyResult.data); | |
| const isValid = verifyPropertyIntegrity(propertyHashData, blockchainListing.data_hash); |
🤖 Prompt for AI Agents
In apps/backend/src/services/property.service.ts around lines 653-655, do not
call propertyToHashData(propertyResult.data ?? {}) because that forges an empty
object and leads to undefined property.location (and TypeScript errors); instead
check that propertyResult.data exists and has a populated location first, and if
it does not, early-return or throw a descriptive error / log and abort
verification; then pass the actual Property object (typed) to propertyToHashData
and only call verifyPropertyIntegrity when the required fields are present.
| insert: mock(() => ({ | ||
| select: mock(() => Promise.resolve({ data: [], error: null })), | ||
| then: mock((callback: any) => callback({ data: [], error: null })) | ||
| then: mock((callback: any) => callback({ data: [], error: null })), | ||
| })), | ||
| update: mock(() => ({ |
There was a problem hiding this comment.
Restore insert().select().single() mock behavior
The updated insert mock now returns a plain Promise from select(), which drops the single() helper that our service code calls (supabase.from(...).insert(...).select().single()). With the current shape, that call path will throw TypeError: ...single is not a function, so any “happy path” insert in these tests will blow up before assertions run. Please keep single() available (and still return the resolved payload) when mocking the success case.
insert: mock(() => ({
- select: mock(() => Promise.resolve({ data: [], error: null })),
- then: mock((callback: any) => callback({ data: [], error: null })),
+ select: mock(() => ({
+ single: mock(() => Promise.resolve({ data: [], error: null })),
+ then: mock((callback: any) => callback({ data: [], error: null })),
+ })),
+ then: mock((callback: any) => callback({ data: [], error: null })),
})),📝 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.
| insert: mock(() => ({ | |
| select: mock(() => Promise.resolve({ data: [], error: null })), | |
| then: mock((callback: any) => callback({ data: [], error: null })) | |
| then: mock((callback: any) => callback({ data: [], error: null })), | |
| })), | |
| update: mock(() => ({ | |
| insert: mock(() => ({ | |
| select: mock(() => ({ | |
| single: mock(() => Promise.resolve({ data: [], error: null })), | |
| then: mock((callback: any) => callback({ data: [], error: null })), | |
| })), | |
| then: mock((callback: any) => callback({ data: [], error: null })), | |
| })), | |
| update: mock(() => ({ |
🤖 Prompt for AI Agents
In apps/backend/tests/integration/booking-integration.test.ts around lines 29 to
33, the mock for insert().select() currently returns a raw Promise and no longer
exposes single(), causing a TypeError when production code calls .single();
update the mock so insert() returns an object whose select() returns an object
with both then(...) (or a Promise-like resolved value) and a single() method
that returns the same resolved payload ({ data: [], error: null }) so production
code can chain .select().single() and receive the expected resolved result for
the happy path.
[FEAT] Transform homepage into marketing landing page
Description
Complete transformation of the homepage into a modern marketing landing page with multiple sections to improve user engagement and conversion.
Changes Made
Technical Details
Additional Notes
Related Issues
Closes #130
Checklist
Summary by CodeRabbit
New Features
Enhancements
Refactor