Skip to content

feat: scaffold apps/web/src/app/hotel/[id]/escrow/create/ route place…#84

Open
yusufadeagbo wants to merge 2 commits intosafetrustcr:mainfrom
yusufadeagbo:feat/escrow-create-route-71
Open

feat: scaffold apps/web/src/app/hotel/[id]/escrow/create/ route place…#84
yusufadeagbo wants to merge 2 commits intosafetrustcr:mainfrom
yusufadeagbo:feat/escrow-create-route-71

Conversation

@yusufadeagbo
Copy link
Copy Markdown

@yusufadeagbo yusufadeagbo commented Mar 28, 2026

Closes #71


…holder #71

Summary by CodeRabbit

Release Notes

  • New Features

    • Added escrow creation interface featuring invoice tracking with status display and visual step-by-step process indicator for hotel transactions.
  • Chores

    • Initialized web application infrastructure with build system configuration, TypeScript support, CSS framework setup, and development tooling for monorepo structure.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

📝 Walkthrough

Walkthrough

This pull request establishes a new Next.js web application for a Stellar-based escrow system called SafeTrust. It introduces monorepo configuration, Next.js app scaffolding, Tailwind CSS styling, TypeScript configuration, and initial UI components for escrow creation workflows.

Changes

Cohort / File(s) Summary
Monorepo Setup
package.json, turbo.json, .gitignore
Root package manifest with monorepo scripts and dependencies (turbo, prettier), Turbo pipeline configuration for build, dev, lint tasks, and Git ignore patterns for common artifacts.
Next.js App Configuration
apps/web/next.config.js, apps/web/next-env.d.ts, apps/web/tsconfig.json, apps/web/package.json
Next.js configuration with React strict mode enabled, TypeScript type declarations, TypeScript compiler options with strict checking and path aliases (@/*./src/*), and app-specific npm scripts and dependencies.
Styling & Theme Configuration
apps/web/tailwind.config.ts, apps/web/postcss.config.js, apps/web/src/app/globals.css
Tailwind CSS configuration with custom color tokens and radius values, PostCSS setup for Tailwind and autoprefixer, and global CSS with Tailwind directives, theme variables (:root, .dark), and glassmorphism utility class (.glass).
Layout & Root Components
apps/web/src/app/layout.tsx
Root layout component exporting metadata and rendering HTML document structure with Tailwind styling applied to body.
Escrow UI Components
apps/web/src/components/escrow/InvoiceHeader.tsx, apps/web/src/components/escrow/ProcessStepper.tsx, apps/web/src/components/escrow/XDRSigningFlowStub.tsx
Reusable components for invoice display with status styling, four-step process visualization with active/completed/pending states, and placeholder stub for XDR signing flow integration.
Escrow Creation Page
apps/web/src/app/hotel/[id]/escrow/create/page.tsx
Hotel-specific escrow creation page with dynamic route parameter, two-column layout composing header/stepper components, placeholder image grid, property details, and TODO stub for XDR signing integration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A monorepo springs to life today,
With Next.js apps now here to stay,
Components nestled, configs in place,
Escrow flows through cyber-space—
Stellar trusteth this rabbit's way!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: scaffolding the escrow creation route placeholder at apps/web/src/app/hotel/[id]/escrow/create/. It is clear, specific, and directly reflects the primary objective documented in the PR.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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: 5

🧹 Nitpick comments (8)
apps/web/src/components/escrow/InvoiceHeader.tsx (2)

20-24: Consider replacing nested ternary with object lookup.

The nested ternary for label is functional but an object lookup would be more readable and consistent with STATUS_STYLES.

♻️ Proposed refactor
+const STATUS_LABELS: Record<InvoiceStatus, string> = {
+    pending: 'Pending',
+    paid: 'Paid',
+    blocked: 'Deposit blocked',
+    released: 'Deposit released',
+};
+
 export function InvoiceHeader({
     // ...props
 }) {
-    const label =
-        status === 'pending' ? 'Pending' :
-            status === 'paid' ? 'Paid' :
-                status === 'blocked' ? 'Deposit blocked' :
-                    'Deposit released';
+    const label = STATUS_LABELS[status];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/components/escrow/InvoiceHeader.tsx` around lines 20 - 24,
Replace the nested ternary that computes `label` in InvoiceHeader.tsx with a
simple lookup map: define a `LABELS` object mapping statuses ('pending', 'paid',
'blocked', etc.) to their display strings and set `label` via `LABELS[status] ||
'Deposit released'`; align naming and default with the existing `STATUS_STYLES`
pattern and use the same `status` variable so the change is purely structural
and improves readability.

4-9: Strengthen type safety with explicit status keys.

STATUS_STYLES is typed as Record<string, string> but the status prop is a specific union type. Using a stricter type ensures the styles object stays in sync with valid statuses.

♻️ Proposed type improvement
-const STATUS_STYLES: Record<string, string> = {
+type InvoiceStatus = 'pending' | 'paid' | 'blocked' | 'released';
+
+const STATUS_STYLES: Record<InvoiceStatus, string> = {
     pending: 'bg-pink-100 text-pink-800 border-pink-200',
     paid: 'bg-green-100 text-green-800 border-green-200',
     blocked: 'bg-blue-100 text-blue-800 border-blue-200',
     released: 'bg-lime-100 text-lime-800 border-lime-200',
 };

Then reuse InvoiceStatus in the props type at line 17.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/components/escrow/InvoiceHeader.tsx` around lines 4 - 9,
STATUS_STYLES is currently typed as Record<string,string> which is too loose;
change its type to use the InvoiceStatus union (e.g. declare STATUS_STYLES:
Record<InvoiceStatus, string> or define the object with an as const and
assert/derive Record<InvoiceStatus,string>) so the keys must match valid
statuses, and update the component props to reuse the InvoiceStatus type for the
status prop (ensure the prop type references InvoiceStatus rather than string)
to keep types synchronized.
apps/web/src/components/escrow/ProcessStepper.tsx (1)

32-34: Simplify redundant condition.

The condition isActive && !isCurrent && stepNum < currentStep has redundancy. Given isActive means stepNum <= currentStep and !isCurrent means stepNum !== currentStep, the third clause stepNum < currentStep is already implied.

♻️ Simplified condition
-                                {isActive && !isCurrent && stepNum < currentStep ? '✓' : stepNum}
+                                {isActive && !isCurrent ? '✓' : stepNum}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/components/escrow/ProcessStepper.tsx` around lines 32 - 34, The
ternary condition inside the step indicator is redundant: simplify the
expression {isActive && !isCurrent && stepNum < currentStep ? '✓' : stepNum} by
removing the implied check (stepNum < currentStep) because isActive (stepNum <=
currentStep) combined with !isCurrent (stepNum !== currentStep) already
guarantees stepNum < currentStep; update the JSX in ProcessStepper (the element
rendering the step label using isActive, isCurrent, stepNum, currentStep) to use
the simplified condition {isActive && !isCurrent ? '✓' : stepNum}.
apps/web/src/app/hotel/[id]/escrow/create/page.tsx (2)

94-97: Add accessibility attributes to the textarea.

The textarea is missing id and aria-label attributes for accessibility. Screen readers need these to properly identify the field.

♻️ Proposed fix
                             <textarea
+                                id="internal-notes"
+                                aria-label="Internal notes"
                                 className="w-full text-sm font-medium border-slate-200 rounded-xl p-4 h-32 resize-none focus:ring-2 focus:ring-blue-500 transition-all outline-none bg-slate-50/50 placeholder:text-slate-300"
                                 placeholder="Add private notes for your records..."
                             />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/hotel/`[id]/escrow/create/page.tsx around lines 94 - 97, The
textarea lacks accessibility identifiers; add an id (e.g., id="privateNotes")
and a descriptive aria-label (e.g., aria-label="Private notes for your records")
to the <textarea> element so screen readers can identify it; optionally ensure
any visible <label> uses the same id via htmlFor to associate the control
(update the textarea attributes in the component rendering the textarea).

78-83: Use obviously fake placeholder data for contact information.

The hardcoded phone number and email could be mistaken for real PII. Consider using clearly fictional placeholders (e.g., +1 555-000-0000, example@example.com) to avoid any compliance concerns and make it clear this is placeholder data.

♻️ Proposed fix
                                         <p className="text-slate-700 font-bold flex items-center gap-2">
-                                            <span className="text-slate-400">📞</span> +506 6485 2179
+                                            <span className="text-slate-400">📞</span> +1 555-000-0000
                                         </p>
                                         <p className="text-slate-700 font-bold flex items-center gap-2 underline decoration-blue-200 decoration-2 underline-offset-4 pointer-events-none">
-                                            <span className="text-slate-400">✉️</span> albertoCasas100@gmail.com
+                                            <span className="text-slate-400">✉️</span> owner@example.com
                                         </p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/hotel/`[id]/escrow/create/page.tsx around lines 78 - 83,
Replace the hardcoded contact PII in the two JSX <p> elements (the phone line
with "📞 +506 6485 2179" and the email line with "✉️ albertoCasas100@gmail.com")
with obviously fake placeholder data (for example "+1 555-000-0000" and
"example@example.com") so the contact info is clearly non‑real; update the text
content of those same <p> nodes in the page component to use the placeholder
strings while keeping the existing classes and icons intact.
apps/web/src/app/layout.tsx (1)

14-17: Consider using semantic color tokens and preparing for dark mode.

The body uses hardcoded bg-slate-50/50 instead of the semantic bg-background token defined in your theme. For consistency and dark mode support, consider using the theme tokens and adding suppressHydrationWarning to prevent hydration mismatches when toggling themes.

♻️ Proposed enhancement
     return (
-        <html lang="en">
-            <body className="min-h-screen bg-slate-50/50">{children}</body>
+        <html lang="en" suppressHydrationWarning>
+            <body className="min-h-screen bg-background text-foreground">{children}</body>
         </html>
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/layout.tsx` around lines 14 - 17, Replace the hardcoded
background class on the <body> in layout.tsx (currently className="min-h-screen
bg-slate-50/50") with the semantic theme token (e.g., className="min-h-screen
bg-background") and add suppressHydrationWarning on the <body> element to avoid
hydration mismatches when toggling themes; update any import/usage that expects
theme tokens so dark mode styles (background/foreground tokens) are used
consistently for the children rendering.
package.json (1)

10-13: Pin devDependencies to specific versions for reproducible builds.

Using "latest" for prettier and turbo causes inconsistent behavior across environments and can introduce unexpected breaking changes. Pin to specific versions instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 10 - 13, Update package.json devDependencies to
use fixed version strings instead of "latest": change the entries under
"devDependencies" for "prettier" and "turbo" to specific semver pins (e.g.,
"prettier": "2.8.8" and "turbo": "1.6.5" or whatever tested versions you want)
so builds are reproducible; ensure you choose and document compatible versions,
run npm/yarn install to regenerate lockfile, and run the repo's formatting/build
checks to validate the pinned versions work with existing scripts.
apps/web/package.json (1)

11-18: Pin dependencies to specific versions for reproducible builds.

Several dependencies use "latest" which can cause unexpected breaking changes and build reproducibility issues. Pin them to specific versions.

♻️ Proposed fix
     "dependencies": {
-        "@creit.tech/stellar-wallets-kit": "latest",
+        "@creit.tech/stellar-wallets-kit": "^2.0.1",
         "next": "14.2.0",
         "react": "^18",
         "react-dom": "^18",
-        "lucide-react": "latest",
-        "clsx": "latest",
-        "tailwind-merge": "latest"
+        "lucide-react": "^1.7.0",
+        "clsx": "^2.1.1",
+        "tailwind-merge": "^3.5.0"
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/package.json` around lines 11 - 18, The package.json dependencies
use "latest" which breaks reproducible builds; open apps/web package.json and
replace the "latest" values for "@creit.tech/stellar-wallets-kit",
"lucide-react", "clsx", and "tailwind-merge" with specific, tested semver
versions (prefer exact versions like "1.2.3" rather than the "latest" tag or
loose ranges), save the file, then regenerate the lockfile by running the
project package manager (npm/yarn/pnpm install) to commit the updated lockfile
so CI and other devs get deterministic installs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/package.json`:
- Line 9: The package.json defines a "lint" npm script ("lint": "next lint") but
does not include the required ESLint packages; update devDependencies to add
"eslint" and "eslint-config-next" (and any peer plugins your codebase needs) so
running npm/yarn/npm run lint works; ensure package.json's devDependencies
include at least "eslint" and "eslint-config-next" and then run install to
update lockfile.

In `@apps/web/postcss.config.js`:
- Around line 2-4: postcss.config.js declares the PostCSS plugin "autoprefixer"
but the web package's package.json devDependencies is missing it; open the web
package.json (the web package) and add "autoprefixer" to devDependencies (pick a
compatible version or align with workspace versions), then run the workspace
installer so PostCSS can resolve the plugin during build/dev.

In `@apps/web/src/app/hotel/`[id]/escrow/create/page.tsx:
- Line 13: Remove the unused import XDRSigningFlowStub from the file (it's
imported at the top of page.tsx but never referenced); locate the import
statement "import { XDRSigningFlowStub } from
'@/components/escrow/XDRSigningFlowStub';" and delete it, or alternatively use
XDRSigningFlowStub in the component's JSX/logic if the stub is actually needed
(update the component rendering where appropriate, e.g., in the page component
that handles escrow creation).

In `@package.json`:
- Around line 14-17: Remove `pnpm` from the project's runtime dependencies to
resolve the version conflict with the `packageManager` field: delete the
`"pnpm": "^10.33.0"` entry from the `dependencies` object (or remove the entire
empty `dependencies` object if nothing else is listed), leaving `packageManager:
"pnpm@8.15.4"` as the source of truth for the toolchain version.

In `@turbo.json`:
- Around line 3-18: The turbo.json uses the deprecated top-level key "pipeline"
which is invalid in Turbo 2.x—replace the "pipeline" key with "tasks" preserving
the same nested entries ("build", "dev", "lint") and their settings (e.g.,
"dependsOn", "outputs", "cache", "persistent"); after renaming ensure the
resulting top-level key is "tasks" and validate with your Turbo version (or run
npx `@turbo/codemod` rename-pipeline to automate the change).

---

Nitpick comments:
In `@apps/web/package.json`:
- Around line 11-18: The package.json dependencies use "latest" which breaks
reproducible builds; open apps/web package.json and replace the "latest" values
for "@creit.tech/stellar-wallets-kit", "lucide-react", "clsx", and
"tailwind-merge" with specific, tested semver versions (prefer exact versions
like "1.2.3" rather than the "latest" tag or loose ranges), save the file, then
regenerate the lockfile by running the project package manager (npm/yarn/pnpm
install) to commit the updated lockfile so CI and other devs get deterministic
installs.

In `@apps/web/src/app/hotel/`[id]/escrow/create/page.tsx:
- Around line 94-97: The textarea lacks accessibility identifiers; add an id
(e.g., id="privateNotes") and a descriptive aria-label (e.g.,
aria-label="Private notes for your records") to the <textarea> element so screen
readers can identify it; optionally ensure any visible <label> uses the same id
via htmlFor to associate the control (update the textarea attributes in the
component rendering the textarea).
- Around line 78-83: Replace the hardcoded contact PII in the two JSX <p>
elements (the phone line with "📞 +506 6485 2179" and the email line with "✉️
albertoCasas100@gmail.com") with obviously fake placeholder data (for example
"+1 555-000-0000" and "example@example.com") so the contact info is clearly
non‑real; update the text content of those same <p> nodes in the page component
to use the placeholder strings while keeping the existing classes and icons
intact.

In `@apps/web/src/app/layout.tsx`:
- Around line 14-17: Replace the hardcoded background class on the <body> in
layout.tsx (currently className="min-h-screen bg-slate-50/50") with the semantic
theme token (e.g., className="min-h-screen bg-background") and add
suppressHydrationWarning on the <body> element to avoid hydration mismatches
when toggling themes; update any import/usage that expects theme tokens so dark
mode styles (background/foreground tokens) are used consistently for the
children rendering.

In `@apps/web/src/components/escrow/InvoiceHeader.tsx`:
- Around line 20-24: Replace the nested ternary that computes `label` in
InvoiceHeader.tsx with a simple lookup map: define a `LABELS` object mapping
statuses ('pending', 'paid', 'blocked', etc.) to their display strings and set
`label` via `LABELS[status] || 'Deposit released'`; align naming and default
with the existing `STATUS_STYLES` pattern and use the same `status` variable so
the change is purely structural and improves readability.
- Around line 4-9: STATUS_STYLES is currently typed as Record<string,string>
which is too loose; change its type to use the InvoiceStatus union (e.g. declare
STATUS_STYLES: Record<InvoiceStatus, string> or define the object with an as
const and assert/derive Record<InvoiceStatus,string>) so the keys must match
valid statuses, and update the component props to reuse the InvoiceStatus type
for the status prop (ensure the prop type references InvoiceStatus rather than
string) to keep types synchronized.

In `@apps/web/src/components/escrow/ProcessStepper.tsx`:
- Around line 32-34: The ternary condition inside the step indicator is
redundant: simplify the expression {isActive && !isCurrent && stepNum <
currentStep ? '✓' : stepNum} by removing the implied check (stepNum <
currentStep) because isActive (stepNum <= currentStep) combined with !isCurrent
(stepNum !== currentStep) already guarantees stepNum < currentStep; update the
JSX in ProcessStepper (the element rendering the step label using isActive,
isCurrent, stepNum, currentStep) to use the simplified condition {isActive &&
!isCurrent ? '✓' : stepNum}.

In `@package.json`:
- Around line 10-13: Update package.json devDependencies to use fixed version
strings instead of "latest": change the entries under "devDependencies" for
"prettier" and "turbo" to specific semver pins (e.g., "prettier": "2.8.8" and
"turbo": "1.6.5" or whatever tested versions you want) so builds are
reproducible; ensure you choose and document compatible versions, run npm/yarn
install to regenerate lockfile, and run the repo's formatting/build checks to
validate the pinned versions work with existing scripts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 237b330b-3b5f-46b3-bc1a-b859503be154

📥 Commits

Reviewing files that changed from the base of the PR and between decc85f and 6c50261.

⛔ Files ignored due to path filters (2)
  • apps/web/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (16)
  • pnpm-workspace.yaml
  • .gitignore
  • apps/web/next-env.d.ts
  • apps/web/next.config.js
  • apps/web/package.json
  • apps/web/postcss.config.js
  • apps/web/src/app/globals.css
  • apps/web/src/app/hotel/[id]/escrow/create/page.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/components/escrow/InvoiceHeader.tsx
  • apps/web/src/components/escrow/ProcessStepper.tsx
  • apps/web/src/components/escrow/XDRSigningFlowStub.tsx
  • apps/web/tailwind.config.ts
  • apps/web/tsconfig.json
  • package.json
  • turbo.json

@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 28, 2026

@yusufadeagbo Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

📌feat: scaffold apps/web/src/app/hotel/[id]/escrow/create/ route placeholder

1 participant