Feat/escrow detail route placeholder#87
Feat/escrow detail route placeholder#87Obiajulu-gif wants to merge 1 commit intosafetrustcr:mainfrom
Conversation
|
@Obiajulu-gif 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! 🚀 |
📝 WalkthroughWalkthroughThis pull request introduces an escrow detail page route handler with status-driven view stubs for three escrow states (paid, blocked, released), an apartment detail page with static content, and two accompanying escrow components (InvoiceHeader and ProcessStepper) for rendering invoice information and process tracking. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Pull request overview
Scaffolds the SafeTrust apps/web Next.js application with placeholder routes and UI for the apartment detail and escrow detail “waterfall” flow (Issue #72), plus monorepo build/workspace configuration.
Changes:
- Adds pnpm workspace + Turborepo build wiring (root
package.json,turbo.json,scripts/build.mjs, lockfile). - Introduces a Next.js app skeleton (Root layout, globals, home page, dashboard placeholders).
- Implements placeholder hotel detail and escrow detail routes, including shared escrow UI components (
InvoiceHeader,ProcessStepper).
Reviewed changes
Copilot reviewed 16 out of 20 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| turbo.json | Adds Turborepo build task outputs for Next.js. |
| scripts/build.mjs | Adds a cross-platform build wrapper invoking pnpm --filter @safetrust/web build. |
| pnpm-workspace.yaml | Declares apps/* as workspace packages. |
| pnpm-lock.yaml | Locks dependency graph for the new workspace/web app. |
| package.json | Adds root package metadata + build script entrypoint. |
| .gitignore | Ignores node_modules, turbo cache, and Next build output dirs. |
| apps/web/package.json | Defines the @safetrust/web Next.js app dependencies and scripts. |
| apps/web/next.config.mjs | Configures Next.js build behavior (currently ignores TS/ESLint errors). |
| apps/web/tsconfig.json | Sets TS config + @/* path alias for the web app. |
| apps/web/next-env.d.ts | Next.js TypeScript environment declarations. |
| apps/web/src/app/layout.tsx | Root layout applying global styles and metadata. |
| apps/web/src/app/globals.css | Base styling + responsive display helpers for placeholder sidebars. |
| apps/web/src/app/page.tsx | Home page linking to the hotel detail placeholder. |
| apps/web/src/app/dashboard/layout.tsx | Dashboard layout with a stub sidebar. |
| apps/web/src/app/dashboard/page.tsx | Dashboard placeholder sections (quick actions/overview/table). |
| apps/web/src/app/hotel/[id]/page.tsx | Apartment detail placeholder with “BOOK” CTA into escrow flow. |
| apps/web/src/app/hotel/[id]/escrow/[escrowId]/page.tsx | Escrow detail placeholder route with status-driven stub views. |
| apps/web/src/components/escrow/InvoiceHeader.tsx | Shared invoice/status header component for escrow views. |
| apps/web/src/components/escrow/ProcessStepper.tsx | Shared “Process” stepper component for escrow flow status. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
apps/web/next.config.mjs
Outdated
| const nextConfig = { | ||
| eslint: { | ||
| ignoreDuringBuilds: true, | ||
| }, | ||
| typescript: { | ||
| ignoreBuildErrors: true, |
There was a problem hiding this comment.
Disabling ESLint and TypeScript errors during next build makes CI/production builds succeed even when there are lint/type errors (and can mask real runtime issues). Consider removing these flags or gating them behind a dev-only env var so builds fail in CI.
| const nextConfig = { | |
| eslint: { | |
| ignoreDuringBuilds: true, | |
| }, | |
| typescript: { | |
| ignoreBuildErrors: true, | |
| const allowBuildErrors = process.env.ALLOW_BUILD_ERRORS === 'true'; | |
| const nextConfig = { | |
| eslint: { | |
| ignoreDuringBuilds: allowBuildErrors, | |
| }, | |
| typescript: { | |
| ignoreBuildErrors: allowBuildErrors, |
| function getStubView(status: string | undefined): ViewConfig { | ||
| switch (status) { | ||
| case 'blocked': | ||
| return { label: 'blocked', step: 3, title: 'Payment batch - Escrow Status' }; | ||
| case 'released': | ||
| return { label: 'released', step: 4, title: 'Deposit / Escrow Released' }; | ||
| case 'paid': | ||
| default: | ||
| return { label: 'paid', step: 2, title: 'Payment batch January 2025' }; | ||
| } |
There was a problem hiding this comment.
The header comment says unknown/missing status should redirect to /hotel/[id]/escrow/create, but getStubView currently falls back to paid for any unrecognized status. If the intended behavior is a redirect for invalid values, validate searchParams.status and call redirect(...) when it's not one of the supported stub statuses.
| </button> | ||
| </div> | ||
| <textarea style={styles.input} placeholder="Justification..." /> |
There was a problem hiding this comment.
This <textarea> relies on a placeholder only; it should have an associated <label> (or at least aria-label/aria-labelledby) so screen readers can identify the field even when the placeholder disappears.
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (6)
apps/web/src/components/escrow/InvoiceHeader.tsx (1)
34-39: Use a neutral timestamp prop name for all escrow states.
paidAtis reused for blocked/released states where the value represents a generic status update time. Renaming toupdatedAtwill make integration clearer when real data is wired.Small naming cleanup
export function InvoiceHeader({ invoiceNumber, - paidAt, + updatedAt, status, }: { invoiceNumber: string; - paidAt: string; + updatedAt: string; status: InvoiceStatus; }) { @@ - <p style={{ margin: '0.25rem 0 0', fontWeight: 600 }}>{paidAt}</p> + <p style={{ margin: '0.25rem 0 0', fontWeight: 600 }}>{updatedAt}</p>Also applies to: 87-88
🤖 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 34 - 39, The prop name paidAt on the InvoiceHeader component should be renamed to updatedAt to reflect a neutral status timestamp; update the prop type annotation in the InvoiceHeader parameter list (replace paidAt: string with updatedAt: string), update every internal usage of paidAt within InvoiceHeader (e.g., where you render the timestamp around lines 87-88), and update any places that pass the prop into InvoiceHeader to use updatedAt instead of paidAt so all escrow states (paid/blocked/released) receive a consistently named timestamp prop.apps/web/src/app/globals.css (1)
14-17: Restore clearer global link affordance.Line 14-17 removes default link underlines globally, which can make inline links harder to distinguish from body text. Prefer preserving underlines (or adding a stronger explicit link treatment).
Suggested CSS adjustment
a { color: inherit; - text-decoration: none; + text-decoration: underline; + text-underline-offset: 0.12em; +} + +a:hover { + text-decoration-thickness: 2px; +} + +a:focus-visible { + outline: 2px solid `#2563eb`; + outline-offset: 2px; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/app/globals.css` around lines 14 - 17, The global anchor rule currently removes underlines (selector "a"), which reduces link affordance; update the "a" CSS rule to preserve or reintroduce a clear link treatment by removing text-decoration: none and either restoring the default underline or explicitly adding text-decoration: underline (optionally combined with a distinct link color such as a --link-color variable) so inline links remain visually distinguishable from body text.package.json (1)
5-7: Add root quality-gate scripts alongsidebuild.Keeping only
buildat root makes it easier for lint/type issues to slip through during scaffold iterations. Consider addinglintandtypecheckscripts for CI and local verification.Suggested script additions
"scripts": { - "build": "node scripts/build.mjs" + "build": "node scripts/build.mjs", + "lint": "pnpm --filter `@safetrust/web` lint", + "typecheck": "pnpm --filter `@safetrust/web` typecheck" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 5 - 7, The package.json currently exposes only the "build" script, which allows linting/type errors to be missed; add root-level quality-gate scripts next to "build" such as "lint" (to run ESLint across the repo) and "typecheck" (to run TypeScript's checker/tsc --noEmit or your monorepo typecheck command), and update CI/local docs to invoke these scripts; look for the "scripts" object and add "lint" and "typecheck" entries so maintainers can run npm run lint and npm run typecheck alongside npm run build.scripts/build.mjs (1)
4-10: Build entrypoint bypasses the Turbo task graph.The script invokes the package build directly via
spawnSync, so the task dependencies and outputs defined inturbo.jsonare not exercised from the root build command.Consider routing the build through
turbo run buildto leverage the established task orchestration:Suggested refactor
const result = process.platform === 'win32' - ? spawnSync('cmd.exe', ['/c', 'pnpm', '--filter', '@safetrust/web', 'build'], { + ? spawnSync('cmd.exe', ['/c', 'pnpm', 'exec', 'turbo', 'run', 'build', '--filter=@safetrust/web'], { stdio: 'inherit', }) - : spawnSync('pnpm', ['--filter', '@safetrust/web', 'build'], { + : spawnSync('pnpm', ['exec', 'turbo', 'run', 'build', '--filter=@safetrust/web'], { stdio: 'inherit', });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/build.mjs` around lines 4 - 10, The script currently bypasses Turbo by calling spawnSync with pnpm to build `@safetrust/web` (see process.platform and spawnSync invocations); replace those direct pnpm build calls with a spawnSync invocation that runs the root orchestration command (e.g., "pnpm turbo run build" or "turbo run build") so Turbo's task graph and caching defined in turbo.json are used; update both the Windows branch (cmd.exe ['/c', ...]) and the non-Windows branch (spawnSync('pnpm', [...])) to invoke the turbo run build command instead of the package-level build target.apps/web/src/app/hotel/[id]/escrow/[escrowId]/page.tsx (1)
203-209: Add explicit labels for textareas (don’t rely on placeholders).These fields are not programmatically labeled, which hurts accessibility. Add
<label htmlFor>+idfor each textarea.Proposed fix
- <textarea style={styles.input} placeholder="Justification..." /> + <label htmlFor="escrow-justification">Justification</label> + <textarea id="escrow-justification" style={styles.input} placeholder="Justification..." /> @@ - <textarea style={{ ...styles.input, minHeight: '5rem' }} placeholder="Claims..." /> + <label htmlFor="escrow-claims">Claims</label> + <textarea id="escrow-claims" style={{ ...styles.input, minHeight: '5rem' }} placeholder="Claims..." /> @@ - <textarea style={styles.input} placeholder="Notes..." /> + <label htmlFor="escrow-notes">Notes</label> + <textarea id="escrow-notes" style={styles.input} placeholder="Notes..." />Also applies to: 223-224, 280-281
🤖 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/[escrowId]/page.tsx around lines 203 - 209, The textarea elements (e.g., the Escrow Justification textarea and the other textareas referenced at lines 223-224 and 280-281) lack programmatic labels; add a <label htmlFor="..."> with a matching id on each textarea (for example id="escrow-justification") so the textarea elements have explicit labels tied via htmlFor/id, or alternatively provide an aria-label if a visible label isn't desired; update the JSX around the textarea in the EscrowJustification block and the other two textarea locations to include these ids and label elements to satisfy accessibility requirements.apps/web/src/app/hotel/[id]/page.tsx (1)
37-43: Avoid inlinedisplay: nonefor responsive suggestions panel.The inline
displaymakes visibility depend on CSS override precedence. Move display control fully to stylesheet/class to keep responsive behavior predictable.Proposed fix
aside: { width: '18rem', borderRight: '1px solid `#fed7aa`', padding: '1rem', flexShrink: 0, - display: 'none', } satisfies CSSProperties,Also applies to: 109-109
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/app/hotel/`[id]/page.tsx around lines 37 - 43, The inline style object "aside" currently sets display: 'none' which causes precedence issues; remove the display property from the inline "aside" styles and instead add a CSS class (e.g., responsive-aside) that controls visibility via media queries (show on large screens, hide on small screens) and apply that class to the aside element where the "aside" style object is used; do the same change for the other occurrence referenced (around the second "aside" usage at the later location) so responsive visibility is managed entirely in the stylesheet rather than inline styles.
🤖 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/next.config.mjs`:
- Around line 3-8: The build config currently disables ESLint and TypeScript
build-time checks via the next.config.mjs keys eslint.ignoreDuringBuilds and
typescript.ignoreBuildErrors; revert those to enable build-time enforcement
(remove the ignores or set them to false) and add explicit lint and typecheck
scripts to package.json (e.g., "lint" and "typecheck") plus a CI workflow step
that runs those scripts so lint/type errors fail PRs; ensure any temporary
failures are fixed or gated behind feature branches rather than permanently
disabling eslint.ignoreDuringBuilds or typescript.ignoreBuildErrors.
In `@apps/web/src/app/hotel/`[id]/escrow/[escrowId]/page.tsx:
- Line 115: Replace the personal-looking stub contact data used in the UI (e.g.,
the InfoPair with value "John_s@gmail.com" and the other occurrences noted) with
non-identifying fixture emails such as "tenant@example.com" or
"owner@example.com"; locate the InfoPair usages in the escrow page component
(references: InfoPair and the escrow page component functions/JSX) and update
the value props at the three occurrences to use safe fixture addresses instead
of realistic personal emails.
- Around line 90-100: Update getStubView to use the canonical mapping and
redirect on invalid/absent status: map 'funded' -> the existing 'paid' result
(label 'paid', step 2, title 'Payment batch January 2025'), 'active' -> the
existing 'blocked' result (label 'blocked', step 3, title 'Payment batch -
Escrow Status'), and 'completed' -> the existing 'released' result (label
'released', step 4, title 'Deposit / Escrow Released'); for the default case, do
not return 'paid'—instead trigger a redirect to /hotel/[id]/escrow/create (or
throw/return a sentinel that the caller handling page.tsx uses to perform the
redirect). Ensure the switch in getStubView covers these exact status strings
and that the redirect path is used when status is invalid or undefined.
In `@apps/web/src/app/hotel/`[id]/page.tsx:
- Around line 21-25: The owner fixture currently contains real personal contact
data; update the stub in the owner object (owner.name, owner.email, owner.phone)
to use clearly anonymized placeholder values (e.g. a generic name or "Owner
Name", an obviously fake email like owner@example.com, and a non-personal dummy
phone like +1-555-0100) so no PII is present in the page.tsx fixture returned by
the component or data loader.
- Line 132: The suggestions list contains a hardcoded price string ("$4.000") in
the <p> element; replace it with the same currency formatting used elsewhere
(e.g., call Number(suggestion.price).toLocaleString(locale, { style: 'currency',
currency: 'USD' }) or reuse the app's currency formatter) so values render
consistently; update the JSX that renders the price (the <p style={{ margin: 0,
color: '#ea580c', fontWeight: 600 }}> element) to use the formatted value
instead of the literal "$4.000".
In `@scripts/build.mjs`:
- Line 16: The current exit uses process.exit(result.status ?? 0) which treats
signal-terminated children (where spawnSync sets result.status to null and
result.signal to e.g. "SIGTERM") as success; update the script that handles the
spawnSync result to check result.signal and exit with a non-zero code (e.g., 1)
when result.signal is set, otherwise use result.status (or 0 fallback). Locate
the spawnSync invocation and the exit call (process.exit(result.status ?? 0))
and change the logic to: if (result.signal) exit non-zero; else exit with
result.status ?? 0.
---
Nitpick comments:
In `@apps/web/src/app/globals.css`:
- Around line 14-17: The global anchor rule currently removes underlines
(selector "a"), which reduces link affordance; update the "a" CSS rule to
preserve or reintroduce a clear link treatment by removing text-decoration: none
and either restoring the default underline or explicitly adding text-decoration:
underline (optionally combined with a distinct link color such as a --link-color
variable) so inline links remain visually distinguishable from body text.
In `@apps/web/src/app/hotel/`[id]/escrow/[escrowId]/page.tsx:
- Around line 203-209: The textarea elements (e.g., the Escrow Justification
textarea and the other textareas referenced at lines 223-224 and 280-281) lack
programmatic labels; add a <label htmlFor="..."> with a matching id on each
textarea (for example id="escrow-justification") so the textarea elements have
explicit labels tied via htmlFor/id, or alternatively provide an aria-label if a
visible label isn't desired; update the JSX around the textarea in the
EscrowJustification block and the other two textarea locations to include these
ids and label elements to satisfy accessibility requirements.
In `@apps/web/src/app/hotel/`[id]/page.tsx:
- Around line 37-43: The inline style object "aside" currently sets display:
'none' which causes precedence issues; remove the display property from the
inline "aside" styles and instead add a CSS class (e.g., responsive-aside) that
controls visibility via media queries (show on large screens, hide on small
screens) and apply that class to the aside element where the "aside" style
object is used; do the same change for the other occurrence referenced (around
the second "aside" usage at the later location) so responsive visibility is
managed entirely in the stylesheet rather than inline styles.
In `@apps/web/src/components/escrow/InvoiceHeader.tsx`:
- Around line 34-39: The prop name paidAt on the InvoiceHeader component should
be renamed to updatedAt to reflect a neutral status timestamp; update the prop
type annotation in the InvoiceHeader parameter list (replace paidAt: string with
updatedAt: string), update every internal usage of paidAt within InvoiceHeader
(e.g., where you render the timestamp around lines 87-88), and update any places
that pass the prop into InvoiceHeader to use updatedAt instead of paidAt so all
escrow states (paid/blocked/released) receive a consistently named timestamp
prop.
In `@package.json`:
- Around line 5-7: The package.json currently exposes only the "build" script,
which allows linting/type errors to be missed; add root-level quality-gate
scripts next to "build" such as "lint" (to run ESLint across the repo) and
"typecheck" (to run TypeScript's checker/tsc --noEmit or your monorepo typecheck
command), and update CI/local docs to invoke these scripts; look for the
"scripts" object and add "lint" and "typecheck" entries so maintainers can run
npm run lint and npm run typecheck alongside npm run build.
In `@scripts/build.mjs`:
- Around line 4-10: The script currently bypasses Turbo by calling spawnSync
with pnpm to build `@safetrust/web` (see process.platform and spawnSync
invocations); replace those direct pnpm build calls with a spawnSync invocation
that runs the root orchestration command (e.g., "pnpm turbo run build" or "turbo
run build") so Turbo's task graph and caching defined in turbo.json are used;
update both the Windows branch (cmd.exe ['/c', ...]) and the non-Windows branch
(spawnSync('pnpm', [...])) to invoke the turbo run build command instead of the
package-level build target.
🪄 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: 6aa5a845-8e73-4ae1-9a29-26fa86e78def
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
pnpm-workspace.yaml.gitignoreapps/web/next-env.d.tsapps/web/next.config.mjsapps/web/package.jsonapps/web/src/app/dashboard/layout.tsxapps/web/src/app/dashboard/page.tsxapps/web/src/app/globals.cssapps/web/src/app/hotel/[id]/escrow/[escrowId]/page.tsxapps/web/src/app/hotel/[id]/page.tsxapps/web/src/app/layout.tsxapps/web/src/app/page.tsxapps/web/src/components/escrow/InvoiceHeader.tsxapps/web/src/components/escrow/ProcessStepper.tsxapps/web/tsconfig.jsonpackage.jsonpnpm-workspace.yamlscripts/build.mjsturbo.json
apps/web/next.config.mjs
Outdated
| eslint: { | ||
| ignoreDuringBuilds: true, | ||
| }, | ||
| typescript: { | ||
| ignoreBuildErrors: true, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify current guardrail state and whether alternative scripts exist.
rg -n '"lint"|"typecheck"|ignoreDuringBuilds|ignoreBuildErrors' \
package.json apps/web/package.json apps/web/next.config.mjs -C2Repository: safetrustcr/dApp-SafeTrust
Length of output: 406
🏁 Script executed:
cat apps/web/package.jsonRepository: safetrustcr/dApp-SafeTrust
Length of output: 465
🏁 Script executed:
find . -name "package.json" -type f | head -5 | xargs catRepository: safetrustcr/dApp-SafeTrust
Length of output: 609
🏁 Script executed:
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -3 | xargs catRepository: safetrustcr/dApp-SafeTrust
Length of output: 52
🏁 Script executed:
cat -n apps/web/tsconfig.jsonRepository: safetrustcr/dApp-SafeTrust
Length of output: 888
Build is configured to ignore both lint and type errors.
Lines 4 and 7 disable core build-time safeguards while tsconfig.json enforces strict mode. No lint or typecheck scripts exist in package.json and no CI workflows are configured, leaving no alternative quality gates. Invalid code can be promoted to production undetected.
Suggested fix:
const nextConfig = {
eslint: {
- ignoreDuringBuilds: true,
+ ignoreDuringBuilds: false,
},
typescript: {
- ignoreBuildErrors: true,
+ ignoreBuildErrors: false,
},
};📝 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.
| eslint: { | |
| ignoreDuringBuilds: true, | |
| }, | |
| typescript: { | |
| ignoreBuildErrors: true, | |
| }, | |
| eslint: { | |
| ignoreDuringBuilds: false, | |
| }, | |
| typescript: { | |
| ignoreBuildErrors: false, | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/next.config.mjs` around lines 3 - 8, The build config currently
disables ESLint and TypeScript build-time checks via the next.config.mjs keys
eslint.ignoreDuringBuilds and typescript.ignoreBuildErrors; revert those to
enable build-time enforcement (remove the ignores or set them to false) and add
explicit lint and typecheck scripts to package.json (e.g., "lint" and
"typecheck") plus a CI workflow step that runs those scripts so lint/type errors
fail PRs; ensure any temporary failures are fixed or gated behind feature
branches rather than permanently disabling eslint.ignoreDuringBuilds or
typescript.ignoreBuildErrors.
There was a problem hiding this comment.
@sotoJ24, understood! Just to leave a note for future reference: when the scaffolding is ready for production, re-enabling these checks (setting ignoreDuringBuilds: false and ignoreBuildErrors: false) alongside dedicated lint and typecheck scripts will help catch issues before they reach production. Happy to help when you're ready to make that change!
| function getStubView(status: string | undefined): ViewConfig { | ||
| switch (status) { | ||
| case 'blocked': | ||
| return { label: 'blocked', step: 3, title: 'Payment batch - Escrow Status' }; | ||
| case 'released': | ||
| return { label: 'released', step: 4, title: 'Deposit / Escrow Released' }; | ||
| case 'paid': | ||
| default: | ||
| return { label: 'paid', step: 2, title: 'Payment batch January 2025' }; | ||
| } | ||
| } |
There was a problem hiding this comment.
Implement canonical status mapping + redirect fallback (objective mismatch).
getStubView currently treats unknown/missing status as paid. The issue objective calls for mapping funded→paid, active→blocked, completed→released, and redirecting default/invalid states to /hotel/[id]/escrow/create.
Proposed fix
+import { redirect } from 'next/navigation';
import { InvoiceHeader } from '@/components/escrow/InvoiceHeader';
import { ProcessStepper } from '@/components/escrow/ProcessStepper';
import type { CSSProperties } from 'react';
type StubStatus = 'paid' | 'blocked' | 'released';
+type QueryStatus = StubStatus | 'funded' | 'active' | 'completed';
-function getStubView(status: string | undefined): ViewConfig {
+function getStubView(status: QueryStatus | undefined): ViewConfig | null {
switch (status) {
+ case 'active':
case 'blocked':
return { label: 'blocked', step: 3, title: 'Payment batch - Escrow Status' };
+ case 'completed':
case 'released':
return { label: 'released', step: 4, title: 'Deposit / Escrow Released' };
+ case 'funded':
case 'paid':
- default:
return { label: 'paid', step: 2, title: 'Payment batch January 2025' };
+ default:
+ return null;
}
}
@@
- const view = getStubView(searchParams?.status);
+ const view = getStubView(searchParams?.status as QueryStatus | undefined);
+ if (!view) {
+ redirect(`/hotel/${params.id}/escrow/create`);
+ }Also applies to: 246-246
🤖 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/[escrowId]/page.tsx around lines 90 -
100, Update getStubView to use the canonical mapping and redirect on
invalid/absent status: map 'funded' -> the existing 'paid' result (label 'paid',
step 2, title 'Payment batch January 2025'), 'active' -> the existing 'blocked'
result (label 'blocked', step 3, title 'Payment batch - Escrow Status'), and
'completed' -> the existing 'released' result (label 'released', step 4, title
'Deposit / Escrow Released'); for the default case, do not return 'paid'—instead
trigger a redirect to /hotel/[id]/escrow/create (or throw/return a sentinel that
the caller handling page.tsx uses to perform the redirect). Ensure the switch in
getStubView covers these exact status strings and that the redirect path is used
when status is invalid or undefined.
There was a problem hiding this comment.
@sotoJ24 — Noted! If you'd like to revisit the canonical status mapping and redirect fallback for getStubView in a follow-up PR, feel free to reference the proposed fix in this comment. No pressure to address it now.
😔
(\(\
( -.-)
o_(")(")
| return ( | ||
| <div style={{ display: 'grid', gap: '1.5rem' }}> | ||
| <div style={styles.splitGrid}> | ||
| <InfoPair label="Billed to" value="John_s@gmail.com" /> |
There was a problem hiding this comment.
Replace personal-looking stub contact data with safe fixture values.
Committing realistic emails in UI stubs is a privacy/compliance risk. Use non-identifying fixtures (e.g., tenant@example.com, owner@example.com) across placeholders.
Also applies to: 173-173, 181-181
🤖 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/[escrowId]/page.tsx at line 115, Replace
the personal-looking stub contact data used in the UI (e.g., the InfoPair with
value "John_s@gmail.com" and the other occurrences noted) with non-identifying
fixture emails such as "tenant@example.com" or "owner@example.com"; locate the
InfoPair usages in the escrow page component (references: InfoPair and the
escrow page component functions/JSX) and update the value props at the three
occurrences to use safe fixture addresses instead of realistic personal emails.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check current state of the escrow page for email stub values
rg -n "gmail\|example\.com\|@" apps/web/src/app/hotel/
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check if the file exists and look for email values
fd "page.tsx" apps/web/src/app/hotel --exec cat {}
Length of output: 15388
@sotoJ24, the personal-looking emails are still present in the current code. Here are all four occurrences that need updating:
| File | Location | Current value | Suggested value |
|---|---|---|---|
escrow/[escrowId]/page.tsx |
PaidStubView – "Billed to" |
John_s@gmail.com |
tenant@example.com |
escrow/[escrowId]/page.tsx |
BlockedStubView – Tenant Email |
John_s@gmail.com |
tenant@example.com |
escrow/[escrowId]/page.tsx |
BlockedStubView – Owner Email |
albertoCasas100@gmail.com |
owner@example.com |
hotel/[id]/page.tsx |
STUB_APARTMENT.owner.email |
albertoCasas100@gmail.com |
owner@example.com |
Would you like me to plan the code changes to swap these out for safe fixture values?
| owner: { | ||
| name: 'Alberto Casas', | ||
| email: 'albertoCasas100@gmail.com', | ||
| phone: '+506 64852179', | ||
| }, |
There was a problem hiding this comment.
Use anonymized fixture contacts in stubs.
owner.email/owner.phone should use clearly fake, non-personal fixtures to avoid accidental PII leakage in shipped placeholder content.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/hotel/`[id]/page.tsx around lines 21 - 25, The owner fixture
currently contains real personal contact data; update the stub in the owner
object (owner.name, owner.email, owner.phone) to use clearly anonymized
placeholder values (e.g. a generic name or "Owner Name", an obviously fake email
like owner@example.com, and a non-personal dummy phone like +1-555-0100) so no
PII is present in the page.tsx fixture returned by the component or data loader.
There was a problem hiding this comment.
@sotoJ24, here's the fix to replace the real-looking contact data with clearly anonymized placeholder values:
- Replace
owner.name,owner.email, andowner.phoneinSTUB_APARTMENTwith generic, obviously fake values
Failed to handle agent chat message. Please try again.
| <p style={{ margin: '0.25rem 0', color: '#78716c' }}> | ||
| 329 Calle santos, San José | ||
| </p> | ||
| <p style={{ margin: 0, color: '#ea580c', fontWeight: 600 }}>$4.000</p> |
There was a problem hiding this comment.
Use consistent currency formatting in suggestions list.
$4.000 is inconsistent with the rest of the page (toLocaleString pattern). Standardize formatting to avoid locale/UX confusion.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/hotel/`[id]/page.tsx at line 132, The suggestions list
contains a hardcoded price string ("$4.000") in the <p> element; replace it with
the same currency formatting used elsewhere (e.g., call
Number(suggestion.price).toLocaleString(locale, { style: 'currency', currency:
'USD' }) or reuse the app's currency formatter) so values render consistently;
update the JSX that renders the price (the <p style={{ margin: 0, color:
'#ea580c', fontWeight: 600 }}> element) to use the formatted value instead of
the literal "$4.000".
There was a problem hiding this comment.
@sotoJ24, thanks for the reply! Could you clarify — have you addressed the currency formatting inconsistency, or would you like help implementing the fix? If needed, here's a quick drop-in replacement for the hardcoded $4.000:
<p style={{ margin: 0, color: '#ea580c', fontWeight: 600 }}>
{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(4000)}
</p>Or, if the suggestion cards are eventually driven by real data, you could extract a small helper:
const formatCurrency = (amount: number, locale = 'en-US') =>
new Intl.NumberFormat(locale, { style: 'currency', currency: 'USD' }).format(amount);and use it as {formatCurrency(suggestion.price)} in the JSX. This would keep all price displays consistent across the page.
sotoJ24
left a comment
There was a problem hiding this comment.
Hello Dear @Obiajulu-gif, could you please make the changes request by coderabbit
Also please solve the conflicts of the branch |
|
@sotoJ24 i have fix the error |
| function getStubView(status: string | undefined): ViewConfig { | ||
| switch (status) { | ||
| case 'blocked': | ||
| return { label: 'blocked', step: 3, title: 'Payment batch - Escrow Status' }; | ||
| case 'released': | ||
| return { label: 'released', step: 4, title: 'Deposit / Escrow Released' }; | ||
| case 'paid': | ||
| default: | ||
| return { label: 'paid', step: 2, title: 'Payment batch January 2025' }; | ||
| } |
| function getStubView(status: string | undefined): ViewConfig { | ||
| switch (status) { | ||
| case 'blocked': | ||
| return { label: 'blocked', step: 3, title: 'Payment batch - Escrow Status' }; | ||
| case 'released': | ||
| return { label: 'released', step: 4, title: 'Deposit / Escrow Released' }; | ||
| case 'paid': | ||
| default: | ||
| return { label: 'paid', step: 2, title: 'Payment batch January 2025' }; | ||
| } | ||
| } |
| return ( | ||
| <div style={{ display: 'grid', gap: '1.5rem' }}> | ||
| <div style={styles.splitGrid}> | ||
| <InfoPair label="Billed to" value="John_s@gmail.com" /> |
| </button> | ||
| </div> | ||
| <textarea style={styles.input} placeholder="Justification..." /> |
| owner: { | ||
| name: 'Alberto Casas', | ||
| email: 'albertoCasas100@gmail.com', | ||
| phone: '+506 64852179', | ||
| }, |
| <p style={{ margin: '0.25rem 0', color: '#78716c' }}> | ||
| 329 Calle santos, San José | ||
| </p> | ||
| <p style={{ margin: 0, color: '#ea580c', fontWeight: 600 }}>$4.000</p> |
apps/web/next.config.mjs
Outdated
| const nextConfig = { | ||
| eslint: { | ||
| ignoreDuringBuilds: true, | ||
| }, | ||
| typescript: { | ||
| ignoreBuildErrors: true, |
apps/web/next.config.mjs
Outdated
| eslint: { | ||
| ignoreDuringBuilds: true, | ||
| }, | ||
| typescript: { | ||
| ignoreBuildErrors: true, | ||
| }, |
b1240c3 to
bd24d6b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/src/app/hotel/`[id]/escrow/[escrowId]/page.tsx:
- Line 118: The stub currency string passed to InfoPair is incorrect: "IDR -
Dollar" mixes the ISO code for Indonesian Rupiah with "Dollar"; update the stub
to a consistent code/name pair (for example "IDR - Indonesian Rupiah" or "USD -
Dollar") where InfoPair is rendered so the label/value pair is accurate; locate
the usage in page.tsx where InfoPair is invoked for Currency and replace the
value string accordingly.
🪄 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: 0102339a-e616-44b6-9a8e-5761ac46769f
📒 Files selected for processing (4)
apps/web/src/app/hotel/[id]/escrow/[escrowId]/page.tsxapps/web/src/app/hotel/[id]/page.tsxapps/web/src/components/escrow/InvoiceHeader.tsxapps/web/src/components/escrow/ProcessStepper.tsx
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/components/escrow/InvoiceHeader.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/src/components/escrow/ProcessStepper.tsx
| <InfoPair label="Billed to" value="John_s@gmail.com" /> | ||
| <InfoPair label="Invoice Number" value="INV4257-09-012" /> | ||
| <InfoPair label="Billing details" value="John Smith" /> | ||
| <InfoPair label="Currency" value="IDR - Dollar" /> |
There was a problem hiding this comment.
Currency code inconsistency in stub data.
IDR is the ISO code for Indonesian Rupiah, not Dollar (which would be USD). While this is stub data, it could cause confusion if used as a template.
💡 Proposed fix
- <InfoPair label="Currency" value="IDR - Dollar" />
+ <InfoPair label="Currency" value="USD - US Dollar" />📝 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.
| <InfoPair label="Currency" value="IDR - Dollar" /> | |
| <InfoPair label="Currency" value="USD - US Dollar" /> |
🤖 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/[escrowId]/page.tsx at line 118, The stub
currency string passed to InfoPair is incorrect: "IDR - Dollar" mixes the ISO
code for Indonesian Rupiah with "Dollar"; update the stub to a consistent
code/name pair (for example "IDR - Indonesian Rupiah" or "USD - Dollar") where
InfoPair is rendered so the label/value pair is accurate; locate the usage in
page.tsx where InfoPair is invoked for Currency and replace the value string
accordingly.
There was a problem hiding this comment.
Dear @Obiajulu-gif, please fix your pull request so we can merge it
This pull request sets up the initial structure and UI stubs for the SafeTrust web application using Next.js. It introduces placeholder pages and components for the apartment booking and escrow management flows, applies consistent styling, and configures the project for development. The changes are organized into project setup, layout and global styles, and feature-specific UI stubs.
Project setup and configuration:
package.jsonfor the web app with Next.js, React, TypeScript, and related dependencies, along with basic scripts for development and production.next.config.mjsfile that configures Next.js to ignore ESLint and TypeScript errors during builds to streamline initial development.Layout and global styles:
RootLayoutinlayout.tsxthat wraps all pages and imports a newglobals.cssstylesheet for consistent base styling. [1] [2]Feature-specific UI stubs:
dashboard/layout.tsx) and dashboard page (dashboard/page.tsx) with placeholders for sidebar and dashboard widgets. [1] [2]hotel/[id]/page.tsx) with a stubbed apartment object, gallery, amenities, and suggestions sidebar. (apps/web/src/app/hotel/[id]/page.tsxR1-R189)hotel/[id]/escrow/[escrowId]/page.tsx) with stubbed views for different escrow statuses, using a newInvoiceHeadercomponent for status display. (apps/web/src/app/hotel/[id]/escrow/[escrowId]/page.tsxR1-R293, apps/web/src/components/escrow/InvoiceHeader.tsxR1-R93)These changes provide a scaffold for further development, with clear TODOs indicating where real data and components will be integrated as the project progresses.
Closes #72
Summary by CodeRabbit
Release Notes