feat: add staging environment warning banner#73
Conversation
Add plan for StagingBanner component with login and compact variants, shown only when VITE_ENVIRONMENT=staging. Orange warning color scheme on both login page and file browser AppShell. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ariants - Renders only when VITE_ENVIRONMENT=staging, returns null otherwise - Login variant: fixed position overlay with title and disclaimer text - Compact variant: 36px flow element for AppShell integration - Orange #FF6B00 on #3d1a00 background with JetBrains Mono font - data-testid="staging-banner" for E2E testability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Login page renders StagingBanner with fixed overlay above login-container - AppShell uses flex wrapper with compact banner above grid (staging only) - Non-staging code paths remain completely unchanged (zero risk) - Build verified with pnpm --filter web build Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Quick task 004 summary - STATE.md updated with task record - Learnings: GSD quick tasks must use feature branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThe PR adds a frontend-design plugin with skill documentation, introduces a new reusable StagingBanner React component that conditionally renders environment warnings in staging mode, and integrates it into Login and AppShell pages. Documentation and planning files are updated to reflect completed tasks and lessons learned. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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 |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a staging-only warning banner to the web UI so testers don’t confuse staging with production, gated by import.meta.env.VITE_ENVIRONMENT === 'staging'.
Changes:
- Introduces a reusable
StagingBannercomponent withloginandcompactvariants (rendersnulloutside staging). - Integrates the banner into the Login route and the authenticated app shell layout (above header).
- Adds/updates planning and learning notes documenting the quick task and process learnings.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/web/src/components/StagingBanner.tsx | New staging-gated banner component (login + compact variants). |
| apps/web/src/routes/Login.tsx | Renders the login-variant banner on the login page (non-loading path). |
| apps/web/src/components/layout/AppShell.tsx | Wraps AppShell in staging to show compact banner above the grid layout. |
| .planning/quick/004-add-staging-environment-banner/004-PLAN.md | Quick task plan document added (contains some metadata that doesn’t match implementation). |
| .planning/quick/004-add-staging-environment-banner/004-SUMMARY.md | Quick task summary document added. |
| .planning/STATE.md | Updates planning state “Last activity” and quick task table. |
| .learnings/2026-02-09-gsd-quick-must-use-feature-branches.md | Adds process learning about using feature branches for quick tasks. |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.planning/STATE.md (1)
324-324:⚠️ Potential issue | 🟡 MinorStale "Last updated" footer — still references Quick Task 003.
Line 15 says task 004 is the last activity, but the footer on Line 324 still reads "after completing Quick Task 003". Should be updated for consistency.
apps/web/src/routes/Login.tsx (1)
25-32:⚠️ Potential issue | 🟡 MinorLoading state omits the staging banner.
Users on staging will momentarily see the loading screen without the banner, then it appears once auth check completes. This is a minor visual inconsistency but unlikely to cause confusion given the transient nature of the loading state.
Optional fix to add banner to loading state
if (isLoading) { return ( - <div className="login-container"> - <MatrixBackground /> - <div className="loading">initializing...</div> - </div> + <> + <StagingBanner variant="login" /> + <div className="login-container"> + <MatrixBackground /> + <div className="loading">initializing...</div> + </div> + </> ); }
🤖 Fix all issues with AI agents
In `@apps/web/src/components/StagingBanner.tsx`:
- Around line 47-58: The span in StagingBanner.tsx uses a semi-transparent color
'#FF6B0088' which yields insufficient contrast; update the inline style's color
value (the color property on the span in the StagingBanner component) to a fully
opaque, dimmer color such as '#CC6A20' (or another value that meets WCAG AA for
11px text) and verify the chosen hex meets contrast requirements against the
background before committing.
- Around line 56-57: In the StagingBanner component the string fragment "// This
is a staging instance for testing purposes only. No guarantees are made
regarding data safety or security." is inside JSX children and the leading "//"
is being rendered to users; update the JSX in StagingBanner to remove the "//"
prefix so the message reads as normal text, or if the intent was a developer
comment, move the text out of children and use a JSX comment like {/* ... */}
instead; locate the text in the StagingBanner component and apply one of these
fixes to prevent the comment markers from appearing in the UI.
🧹 Nitpick comments (2)
apps/web/src/components/layout/AppShell.tsx (1)
17-43: Duplicated shell content is acceptable given the design goal, but worth noting.The staging/non-staging branches duplicate the inner shell markup (Lines 27–30 vs 38–41). Since
import.meta.env.VITE_ENVIRONMENTis statically replaced by Vite at build time, dead-code elimination will strip the unused branch in production — so there's no runtime cost. The explicit separation keeps the non-staging path untouched, matching the stated "zero production risk" goal.If the shell layout grows more complex over time, consider extracting the inner content to avoid divergence:
Optional DRY refactor
export function AppShell({ children }: AppShellProps) { const isStaging = import.meta.env.VITE_ENVIRONMENT === 'staging'; + const shell = ( + <div className="app-shell" data-testid="app-shell" style={isStaging ? { height: 'auto', flex: 1 } : undefined}> + <AppHeader /> + <AppSidebar /> + <main className="app-main">{children}</main> + <AppFooter /> + </div> + ); + + if (isStaging) { + return ( + <div style={{ display: 'flex', flexDirection: 'column', height: '100vh', overflow: 'hidden' }}> + <StagingBanner variant="compact" /> + {shell} + </div> + ); + } + + return shell; - if (isStaging) { - return ( - <div - style={{ display: 'flex', flexDirection: 'column', height: '100vh', overflow: 'hidden' }} - > - <StagingBanner variant="compact" /> - <div className="app-shell" data-testid="app-shell" style={{ height: 'auto', flex: 1 }}> - <AppHeader /> - <AppSidebar /> - <main className="app-main">{children}</main> - <AppFooter /> - </div> - </div> - ); - } - - return ( - <div className="app-shell" data-testid="app-shell"> - <AppHeader /> - <AppSidebar /> - <main className="app-main">{children}</main> - <AppFooter /> - </div> - ); }apps/web/src/components/StagingBanner.tsx (1)
15-61: Consider addingrole="alert"orrole="banner"for screen readers.The staging warning conveys important context but has no ARIA semantics. Adding
role="alert"(or at minimumrole="banner") to the outer<div>would help assistive technology users understand the environment context. As per coding guidelines, accessibility concerns should be addressed for the React frontend.Also applies to: 63-92
- Fix Biome noCommentText lint: wrap // disclaimer in JSX expression - Fix contrast: replace semi-transparent #FF6B0088 with solid #994400 - Add role="banner" to both variants for screen reader accessibility - Show staging banner during login loading state too - Fix stale STATE.md footer referencing Quick Task 003 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
StagingBannercomponent that renders only whenVITE_ENVIRONMENT=staging#FF6B00on#3d1a00) contrasts clearly with the green terminal themeTest plan
VITE_ENVIRONMENT=staging pnpm --filter web devand verify banner appears on login pagepnpm --filter web dev(no env var) and verify no banner appears anywherepnpm --filter web buildpasses🤖 Generated with Claude Code
Summary by CodeRabbit