Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/web/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { StorybookConfig } from '@storybook/nextjs';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/nextjs',
options: {},
},
docs: {
autodocs: 'tag',
},
staticDirs: ['../public'],
};
export default config;
17 changes: 17 additions & 0 deletions apps/web/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Preview } from '@storybook/react';

import '../src/app/globals.css';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
110 changes: 110 additions & 0 deletions apps/web/biome_errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
src/app/tenant-dashboard/page.tsx:119:39 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unexpected any. Specify a different type.

117 │ }, []);
118 │
> 119 │ const handleViewDetails = (booking: any): void => {
│ ^^^
120 │ // Legacy mapping or handle directly
121 │ const found = apiBookings.find((b) => b.id === booking.id);

i any disables many type checking rules. Its use should be avoided.


src/app/tenant-dashboard/page.tsx:128:41 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unexpected any. Specify a different type.

126 │ };
127 │
> 128 │ const handleCancelBooking = (booking: any): void => {
│ ^^^
129 │ const found = apiBookings.find((b) => b.id === booking.id);
130 │ if (found) {

i any disables many type checking rules. Its use should be avoided.


src/app/tenant-dashboard/page.tsx:359:29 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unexpected any. Specify a different type.

357 │ ) : user ? (
358 │ <ProfileManagement
> 359 │ user={user as any}
│ ^^^
360 │ onUpdateProfile={handleUpdateUser as any}
361 │ onUploadAvatar={async (file) => {

i any disables many type checking rules. Its use should be avoided.


src/app/tenant-dashboard/page.tsx:360:52 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unexpected any. Specify a different type.

358 │ <ProfileManagement
359 │ user={user as any}
> 360 │ onUpdateProfile={handleUpdateUser as any}
│ ^^^
361 │ onUploadAvatar={async (file) => {
362 │ await apiUploadAvatar(user.id.toString(), file);

i any disables many type checking rules. Its use should be avoided.


src/app/tenant-dashboard/page.tsx:396:45 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unexpected any. Specify a different type.

394 │ walletBalance={walletBalance}
395 │ pendingTransactions={pendingTransactions}
> 396 │ transactions={transactions as any}
│ ^^^
397 │ onExportTransactions={apiExportTransactions}
398 │ />

i any disables many type checking rules. Its use should be avoided.


src/app/tenant-dashboard/page.tsx format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Formatter would have printed the following content:

207 207 │ <div className="fixed top-4 right-4 z-50 max-w-sm">
208 208 │ <div
209 │ - ··········className={`rounded-lg·p-4·shadow-lg·${toast.type·===·'success'
210 │ - ············?·'bg-green-100·border·border-green-200·text-green-800'
211 │ - ············:·'bg-red-100·border·border-red-200·text-red-800'
212 │ - ············}`}
209 │ + ··········className={`rounded-lg·p-4·shadow-lg·${
210 │ + ············toast.type·===·'success'
211 │ + ··············?·'bg-green-100·border·border-green-200·text-green-800'
212 │ + ··············:·'bg-red-100·border·border-red-200·text-red-800'
213 │ + ··········}`}
213 214 │ >
214 215 │ <div className="flex items-center">
······· │
316 317 │ type="button"
317 318 │ onClick={() => setActiveTab(tab.id)}
318 │ - ··················className={`flex·items-center·space-x-2·py-4·px-1·border-b-2·font-medium·text-sm·${activeTab·===·tab.id
319 │ - ····················?·'border-blue-500·text-blue-600·dark:text-blue-400'
320 │ - ····················:·'border-transparent·text-gray-500·dark:text-white·hover:border-gray-300'
321 │ - ····················}`}
319 │ + ··················className={`flex·items-center·space-x-2·py-4·px-1·border-b-2·font-medium·text-sm·${
320 │ + ····················activeTab·===·tab.id
321 │ + ······················?·'border-blue-500·text-blue-600·dark:text-blue-400'
322 │ + ······················:·'border-transparent·text-gray-500·dark:text-white·hover:border-gray-300'
323 │ + ··················}`}
322 324 │ >
323 325 │ <Icon className="w-5 h-5" />


Checked 1 file in 7ms. No fixes applied.
Found 6 errors.
check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Some errors were emitted while running checks.


Comment on lines +1 to +110
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check for files with lint/error/biome patterns
echo "=== Looking for lint/error output files ==="
fd -e txt -e log | rg -i "error|lint|biome|biome_errors" || echo "No obvious lint output files found"

# Check what's in the actual file (if it exists)
if [ -f "apps/web/biome_errors.txt" ]; then
  echo "=== File exists: apps/web/biome_errors.txt ==="
  wc -l apps/web/biome_errors.txt
  head -20 apps/web/biome_errors.txt
fi

# Check .gitignore
if [ -f .gitignore ]; then
  echo "=== Checking .gitignore for relevant patterns ==="
  rg -i "biome|lint|\.txt|\.log" .gitignore || echo "No matching patterns in .gitignore"
else
  echo "No .gitignore found"
fi

# Check for any biome config
echo "=== Checking for biome config ==="
fd -e "json|jsonc" | rg -i "biome" | head -20

# Check git status to see if this file is being added
echo "=== Checking git info ==="
git ls-files apps/web/biome_errors.txt 2>/dev/null && echo "File is tracked" || echo "File is not currently tracked"

Repository: Stellar-Rent/stellar-rent

Length of output: 1111


Remove this lint error log file from version control and fix the source errors directly.

Committing lint error output files is not standard practice. The file apps/web/biome_errors.txt is currently tracked in git, but it should not be. The 6 noExplicitAny errors and formatting issues documented here should be resolved in the source file (src/app/tenant-dashboard/page.tsx) rather than committed to the repository.

Required fixes:

  1. Remove the file from the PR
  2. Fix the documented errors in src/app/tenant-dashboard/page.tsx:
    • Define proper types for booking parameter in handleViewDetails and handleCancelBooking (lines 119, 128)
    • Remove as any type assertions for user, handleUpdateUser, and transactions props (lines 359, 360, 396)
    • Run formatter to resolve the reported formatting issues (lines 207-213, 318-321)

If these issues require deferred attention, track them via GitHub issues or a tracking document instead.

🧰 Tools
🪛 LanguageTool

[grammar] ~104-~104: Ensure spelling is correct
Context: ...Name="w-5 h-5" /> Checked 1 file in 7ms. No fixes applied. Found 6 errors. chec...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
In `@apps/web/biome_errors.txt` around lines 1 - 110, Delete the generated lint
output file from the PR and fix the root TypeScript and formatting issues in
src/app/tenant-dashboard/page.tsx: replace the any types by adding a Booking
type/interface and use it for the booking parameter in handleViewDetails and
handleCancelBooking (these functions reference apiBookings and booking.id),
remove the `as any` assertions passed into <ProfileManagement> (user prop,
onUpdateProfile which is handleUpdateUser, and transactions) by typing user,
handleUpdateUser, and transactions correctly according to the ProfileManagement
prop types, and run the code formatter/Prettier to fix the reported JSX
formatting inconsistencies.

24 changes: 22 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
"lint": "next lint",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed"
"test:e2e:headed": "playwright test --headed",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test": "vitest run",
"test:watch": "vitest"
Comment on lines +12 to +16
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n apps/web/package.json | head -100

Repository: Stellar-Rent/stellar-rent

Length of output: 3250


🌐 Web query:

Storybook 8.6.14 Next.js 15 React 18 compatibility

💡 Result:

  • Next.js 15 + React 18: Next.js 15’s App Router uses React 19 (RC), while React 18 is only supported for the Pages Router. [1] If you follow the Next.js 15 upgrade guide for the App Router, the minimum react/react-dom is 19. [2]
  • Storybook 8.6.14 + Next.js 15: Storybook’s @storybook/nextjs framework requires Next.js ≥ 14.1, so Next.js 15 is in-range. [3]
  • Main “gotcha” (React version mismatch): With Next.js 15, @storybook/nextjs can end up rendering with Next’s bundled/compiled React (React 19) even when your app (Pages Router) is on React 18, which can cause inconsistencies/bugs. This is a known issue in Storybook’s tracker. [4]

Practical guidance: If you’re on Next.js 15 App Router, assume React 19 for compatibility; if you must stay on React 18, use Next.js 15 Pages Router—but be aware Storybook may still pull in React 19 via Next’s compiled React unless/until that issue is addressed. [1][4]

Sources:
[1] (nextjs.org)
[2] (nextjs.org)
[3] (storybook.js.org)
[4] (github.com)

Citations:


🌐 Web query:

Vitest 4.0.18 jsdom 27 compatibility

💡 Result:

Vitest 4.0.18 should be compatible with jsdom 27 in the sense that Vitest treats jsdom as an optional peer dependency and does not pin it to a specific major version (it’s declared as jsdom: "*" in Vitest 4.x dependency metadata). [1]

What typically breaks on upgrade to jsdom 27 is not Vitest itself, but behavior changes in jsdom that can cause previously-passing DOM/assertion/snapshot tests to fail, e.g. the user-agent stylesheet change (computed styles can differ). [2]

Also ensure your Node.js version meets jsdom 27’s minimum requirements (jsdom 27 requires Node 20+, and 27.0.1 notes tighter minimum patch levels due to dependencies). [2]

Sources: [1] [2]


🌐 Web query:

@testing-library/react 14.2.2 React 18 support

💡 Result:

@testing-library/react@14.2.2 supports React 18—in fact, React Testing Library v13+ requires React v18 (so v14.2.2 is intended for React 18 projects). It also lists react and react-dom as peer dependencies. [1]

If you need to test with React 17 or older, you should use @testing-library/react@12 instead. [1]

Release date: 2024-03-19. [2]

Sources:
[1] (github.com)
[2] (github.com)

Citations:


Critical: Next.js 15.5.3 requires React 19, but package.json specifies React 18.

Storybook 8.6.14, Vitest 4.0.18, jsdom 27.4.0, and @testing-library/react 14.2.2 are mutually compatible. However, Next.js 15 App Router requires React 19 as minimum—React 18 is only supported for the legacy Pages Router. With Next.js 15.5.3, you must upgrade to React 19 or downgrade Next.js. Additionally, there is a known issue where Storybook may render with Next's bundled React 19 even when React 18 is specified, causing inconsistencies.

Also applies to: 57-83

🤖 Prompt for AI Agents
In `@apps/web/package.json` around lines 12 - 16, package.json currently pins
React 18 while Next.js 15.5.3 (App Router) requires React 19; update the
dependency entries "react" and "react-dom" in package.json to a React 19
compatible version (e.g., ^19.0.0) and ensure any peer/dependency constraints
(like next) are aligned, or alternatively downgrade the "next" version to a
release that supports React 18; after changing versions, run yarn/npm install
and re-run Storybook and tests to confirm no mismatched React bundles (fix any
lockfile or hoisting issues so the project uses the same React 19 for Next and
Storybook).

},
"dependencies": {
"stellar-social-sdk": "file:./stellar-social-sdk",
Expand Down Expand Up @@ -51,16 +55,32 @@
},
"devDependencies": {
"@playwright/test": "^1.55.0",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "8.6.14",
"@storybook/blocks": "8.6.14",
"@storybook/nextjs": "8.6.14",
"@storybook/react": "8.6.14",
"@storybook/test": "8.6.14",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "14.2.2",
"@testing-library/user-event": "14.5.2",
"@types/jest": "^30.0.0",
"@types/jsdom": "^27.0.0",
"@types/leaflet": "^1.9.19",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@vitejs/plugin-react": "^5.1.2",
"autoprefixer": "^10.4.17",
"eslint": "^8",
"eslint-config-next": "14.1.0",
"jsdom": "^27.4.0",
"node-loader": "^2.1.0",
"postcss": "^8.4.35",
"storybook": "8.6.14",
"tailwindcss": "^3.4.1",
"typescript": "^5"
"typescript": "^5",
"vitest": "^4.0.18"
}
}
13 changes: 6 additions & 7 deletions apps/web/src/app/booking/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { BookingConfirmation } from '@/components/booking/BookingConfirmation';
import { BookingForm } from '@/components/booking/BookingForm';
import { WalletConnectionModal } from '@/components/booking/WalletConnectionModal';
import { useWallet } from '@/hooks/useWallet';
import { useTheme } from 'next-themes';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import type { DateRange } from 'react-day-picker';
Expand All @@ -20,10 +19,8 @@ interface BookingPageProps {
type BookingFlowStep = 'form' | 'payment' | 'confirmation';

export default function BookingPage({ params }: BookingPageProps) {
const { theme: _theme } = useTheme();
const _router = useRouter();
const { isConnected, connect, publicKey } = useWallet();

const [_selectedDates, _setSelectedDates] = useState<DateRange | undefined>({
from: undefined,
to: undefined,
Expand Down Expand Up @@ -54,7 +51,7 @@ export default function BookingPage({ params }: BookingPageProps) {
const _property = {
id: params.propertyId,
title: 'Luxury Beachfront Villa',
image: '/images/property-placeholder.jpg',
image: '/images/property-placeholder.webp',
pricePerNight: 150,
deposit: 500,
commission: 0.00001,
Expand Down Expand Up @@ -107,21 +104,23 @@ export default function BookingPage({ params }: BookingPageProps) {
propertyId: data.property.id,
userId: publicKey,
dates: data.dates,
checkIn: data.dates.from.toISOString(),
checkOut: data.dates.to.toISOString(),
guests: data.guests,
total: data.totalAmount,
totalAmount: data.totalAmount,
deposit: data.depositAmount,
});

toast.dismiss('create-booking');
toast.success('Booking created! Proceeding to payment.');

setCurrentBookingData({
bookingId: createdBooking.bookingId,
bookingId: createdBooking.data.id,
property: data.property,
dates: data.dates,
guests: data.guests,
totalAmount: data.totalAmount,
escrowAddress: createdBooking.escrowAddress,
escrowAddress: createdBooking.data.escrowAddress || '',
});
Comment on lines 117 to 124
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 | 🟠 Major

Don’t proceed to payment with a missing escrow address.
Falling back to '' can lead to invalid payments or downstream failures. Treat a missing escrowAddress as a hard error and stop the flow.

🛑 Proposed fix (fail fast on missing escrowAddress)
-      setCurrentBookingData({
-        bookingId: createdBooking.data.id,
-        property: data.property,
-        dates: data.dates,
-        guests: data.guests,
-        totalAmount: data.totalAmount,
-        escrowAddress: createdBooking.data.escrowAddress || '',
-      });
+      const escrowAddress = createdBooking.data.escrowAddress;
+      if (!escrowAddress) {
+        throw new Error('Escrow address missing from booking response.');
+      }
+
+      setCurrentBookingData({
+        bookingId: createdBooking.data.id,
+        property: data.property,
+        dates: data.dates,
+        guests: data.guests,
+        totalAmount: data.totalAmount,
+        escrowAddress,
+      });
🤖 Prompt for AI Agents
In `@apps/web/src/app/booking/page.tsx` around lines 117 - 124,
setCurrentBookingData is being populated with createdBooking.data.escrowAddress
defaulting to '', which can allow proceeding without a valid escrow address;
instead, validate createdBooking.data.escrowAddress immediately after the API
response (before calling setCurrentBookingData or starting payment) and treat
its absence as a hard error: stop the flow, surface an error to the user (or
throw) and do not call setCurrentBookingData or continue to the payment step.
Update the logic around createdBooking / createdBooking.data (where
setCurrentBookingData is invoked) to explicitly check escrowAddress and handle
the failure path (show error/return) so downstream code never receives an empty
string escrow address.


setBookingStep('payment');
Expand Down
Loading
Loading