-
Notifications
You must be signed in to change notification settings - Fork 76
feat: loading states and error handling #200 #211
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
Changes from all commits
ebd3e71
88b0788
e1a2c86
27027a4
9826fe4
1c06fa8
d9661c2
bba2a3c
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 |
|---|---|---|
| @@ -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; |
| 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; |
| 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. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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
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. 🧩 Analysis chain🏁 Script executed: cat -n apps/web/package.json | head -100Repository: Stellar-Rent/stellar-rent Length of output: 3250 🌐 Web query:
💡 Result:
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: Citations:
🌐 Web query:
💡 Result: Vitest 4.0.18 should be compatible with jsdom 27 in the sense that Vitest treats 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:
💡 Result:
If you need to test with React 17 or older, you should use Release date: 2024-03-19. [2] Sources: 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 Also applies to: 57-83 🤖 Prompt for AI Agents |
||
| }, | ||
| "dependencies": { | ||
| "stellar-social-sdk": "file:./stellar-social-sdk", | ||
|
|
@@ -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" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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'; | ||
|
|
@@ -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, | ||
|
|
@@ -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, | ||
|
|
@@ -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
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. Don’t proceed to payment with a missing escrow address. 🛑 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 |
||
|
|
||
| setBookingStep('payment'); | ||
|
|
||
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.
🧩 Analysis chain
🏁 Script executed:
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.txtis currently tracked in git, but it should not be. The 6noExplicitAnyerrors 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:
src/app/tenant-dashboard/page.tsx:bookingparameter inhandleViewDetailsandhandleCancelBooking(lines 119, 128)as anytype assertions foruser,handleUpdateUser, andtransactionsprops (lines 359, 360, 396)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