Skip to content

Commit dba2437

Browse files
authored
Merge pull request #21 from newrelic/NR-506774-update-ui
feat: update dashboard UI with new features
2 parents 739694a + b1f7a23 commit dba2437

File tree

13 files changed

+1754
-645
lines changed

13 files changed

+1754
-645
lines changed

frontend_service/.claude.md

Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
# ReliBank Frontend - Context for Claude
2+
3+
## Project Overview
4+
5+
This is a **demo banking application** built to showcase New Relic's observability capabilities. It's intentionally designed with specific behaviors to generate interesting telemetry data. This is NOT a production-ready banking app.
6+
7+
**Key Point**: Many "bugs" are actually intentional demo features. Always check the README before "fixing" things.
8+
9+
---
10+
11+
## Tech Stack
12+
13+
- **Framework**: React Router v7 in **SPA mode** (`ssr: false`)
14+
- **UI**: Material-UI (MUI)
15+
- **State**: React Context API (LoginContext for auth, PageContext for page data)
16+
- **Build**: Vite
17+
- **Language**: TypeScript
18+
- **Deployment**: Kubernetes with Skaffold
19+
20+
---
21+
22+
## Project Structure
23+
24+
```
25+
frontend_service/
26+
├── app/
27+
│ ├── root.tsx # Root layout, LoginContext provider, auth logic
28+
│ ├── routes/
29+
│ │ ├── login.tsx # Login page (path: /)
30+
│ │ ├── dashboard.tsx # Main dashboard with accounts
31+
│ │ ├── support.tsx # Support/chatbot page
32+
│ │ └── settings.tsx # Settings page
33+
│ ├── components/
34+
│ │ ├── layout/
35+
│ │ │ ├── AppLayout.tsx # Main layout wrapper (Header + Sidebar + Footer)
36+
│ │ │ ├── Header.tsx # Top bar with username + notifications
37+
│ │ │ ├── Sidebar.tsx # Left nav menu
38+
│ │ │ └── Footer.tsx # Bottom disclaimer
39+
│ │ └── dashboard/
40+
│ │ └── TransferCard.tsx # Fund transfer component
41+
│ └── types/
42+
│ └── user.ts # TypeScript interfaces
43+
├── react-router.config.ts # IMPORTANT: ssr: false (SPA mode)
44+
└── vite.config.ts # Proxy config for backend services
45+
```
46+
47+
---
48+
49+
## Important: This is SPA Mode, Not SSR
50+
51+
**Configuration**: `react-router.config.ts` has `ssr: false`
52+
53+
This means:
54+
- No server-side rendering
55+
- No hydration issues (all rendering happens client-side)
56+
- Build output only contains `build/client/` (no server bundle)
57+
- Don't use SSR terminology in code or docs
58+
59+
---
60+
61+
## Authentication Flow
62+
63+
### Normal Flow:
64+
1. User visits `/` (login page)
65+
2. User logs in → auth data saved to `sessionStorage`
66+
3. `LoginContext` updates with `userData` (array of account objects)
67+
4. Navigate to `/dashboard`
68+
69+
### State Management:
70+
- **Location**: `app/root.tsx` in the `Layout` component
71+
- **Context**: `LoginContext` provides:
72+
- `isAuthenticated: boolean`
73+
- `userData: UserAccount[] | null` (array of checking/savings accounts)
74+
- `handleLogin(data): void`
75+
- `handleLogout(): void`
76+
- `setUserData(data): void`
77+
- **Persistence**: Syncs with `sessionStorage` automatically
78+
- **Key Pattern**: State initializes to `null`, loads from sessionStorage in `useEffect`
79+
80+
### User Data Structure:
81+
```typescript
82+
userData = [
83+
{ name: 'Alice Checking', account_type: 'checking', balance: 8500.25, routing_number: '123456789' },
84+
{ name: 'Alice Savings', account_type: 'savings', balance: 4000.25, routing_number: '987654321' }
85+
]
86+
```
87+
88+
---
89+
90+
## 🚨 Demo-Specific Behaviors (DO NOT "FIX")
91+
92+
These are **intentional** for New Relic demos:
93+
94+
### 1. No Frontend Overdraft Validation
95+
**Location**: `app/components/dashboard/TransferCard.tsx`
96+
97+
Users can transfer more than their balance. The frontend allows it, backend rejects it.
98+
99+
**Purpose**: Demonstrates backend validation errors and New Relic error telemetry.
100+
101+
**Don't**: Add `if (amount > balance) { showError(); return; }`
102+
103+
### 2. No Rollback on Transfer Errors
104+
**Location**: `app/components/dashboard/TransferCard.tsx`
105+
106+
When a transfer fails:
107+
- UI updates balances immediately (optimistic update)
108+
- API fails → error displays BUT balances stay incorrect
109+
- No rollback to original state
110+
111+
**Purpose**: Visually shows impact of errors, makes errors more obvious in demos.
112+
113+
**Don't**: Add rollback logic like `setUserData(originalUserData)` in catch blocks.
114+
115+
### 3. Mock Data Fallback
116+
**Location**: `app/routes/dashboard.tsx` (line 243)
117+
118+
```typescript
119+
const userData = contextUserData || demoUserData;
120+
```
121+
122+
Dashboard uses demo data if no auth exists. This is intentional for development.
123+
124+
### 4. Broken Theme Toggle Button
125+
**Location**: `app/components/layout/Header.tsx`
126+
127+
A light/dark mode toggle button in the header that intentionally throws a JavaScript error when clicked.
128+
129+
**Purpose**: Demonstrates frontend error tracking, New Relic Browser error reporting, and client-side error handling.
130+
131+
**Behavior**:
132+
- Button is visible in the header (sun/moon icon)
133+
- Clicking it throws: `Error: Theme toggle is not implemented`
134+
- Error is reported to New Relic Browser with context
135+
- Shows impact of uncaught JavaScript errors on user experience
136+
137+
**Don't**: Implement actual theme switching unless explicitly updating demo scenarios.
138+
139+
---
140+
141+
## Development
142+
143+
### Running the App
144+
145+
**Must run from parent directory**:
146+
```bash
147+
cd /path/to/relibank # Parent directory!
148+
skaffold dev
149+
```
150+
151+
**NOT from**:
152+
```bash
153+
cd frontend_service # Wrong! skaffold.yaml is in parent
154+
```
155+
156+
The app runs at: `http://localhost:3000/`
157+
158+
### Debugging with kubectl
159+
160+
**Always use kubectl for debugging pods** - it's faster and more direct than parsing skaffold logs:
161+
162+
```bash
163+
# Check pod status
164+
kubectl get pods -n relibank | grep frontend
165+
166+
# View logs (last 30 lines)
167+
kubectl logs -n relibank deployment/frontend-service --tail=30
168+
169+
# Follow logs in real-time
170+
kubectl logs -n relibank deployment/frontend-service -f
171+
172+
# Check all pods
173+
kubectl get pods -n relibank
174+
```
175+
176+
When debugging issues after a rebuild, use `kubectl logs` to see what's happening in the pod directly instead of reading through skaffold output files.
177+
178+
### Backend Services
179+
180+
Vite proxies requests to Kubernetes services:
181+
- `/accounts-service/*` → accounts-service:5002
182+
- `/chatbot-service/*` → chatbot-service:5003
183+
- `/bill-pay-service/*` → bill-pay-service:5000
184+
185+
### Environment Variables
186+
187+
New Relic config (required):
188+
```bash
189+
VITE_NEW_RELIC_ACCOUNT_ID
190+
VITE_NEW_RELIC_BROWSER_APPLICATION_ID
191+
VITE_NEW_RELIC_LICENSE_KEY
192+
```
193+
194+
### Development Optimizations
195+
196+
**Cache-Busting for Skaffold Rebuilds**
197+
198+
The app includes no-cache meta tags in `app/root.tsx` to prevent stale JS errors after Skaffold rebuilds:
199+
200+
```html
201+
<meta httpEquiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
202+
<meta httpEquiv="Pragma" content="no-cache" />
203+
<meta httpEquiv="Expires" content="0" />
204+
```
205+
206+
**Why:** When Skaffold rebuilds the container, browsers may cache the old `index.html` which references old JS file hashes that no longer exist. This causes errors like "Failed to fetch module" or blank pages.
207+
208+
**Solution:** These headers force the browser to always fetch fresh HTML/JS files. While this adds a small performance overhead, it ensures smooth development. Can be safely removed if needed in the future.
209+
210+
**Vite Dependency Pre-optimization**
211+
212+
Icons used across different pages are pre-optimized in `vite.config.ts` to prevent page reloads on first navigation:
213+
214+
```typescript
215+
optimizeDeps: {
216+
include: [
217+
'@mui/icons-material/Send', // Support page
218+
'@mui/icons-material/Logout', // Header
219+
'@mui/icons-material/Dashboard', // Dashboard page
220+
// ... other icons
221+
]
222+
}
223+
```
224+
225+
**Why:** Without pre-optimization, navigating to a page for the first time triggers Vite to optimize its dependencies, causing a page reload. Pre-optimizing prevents this issue.
226+
227+
---
228+
229+
## Common Tasks
230+
231+
### Testing Error Scenarios
232+
233+
To test transfer failures for demos:
234+
```bash
235+
# Scale down bill-pay service
236+
kubectl scale deployment bill-pay-service -n relibank --replicas=0
237+
238+
# Try transfer in UI → will fail but balances stay incorrect
239+
240+
# Restore service
241+
kubectl scale deployment bill-pay-service -n relibank --replicas=1
242+
```
243+
244+
### Debugging Auth Issues
245+
246+
If user shows "Loading..." or username doesn't display:
247+
1. Check console for `[Layout]` and `[Header]` logs
248+
2. Check `sessionStorage.getItem('userData')` in browser console
249+
3. Verify component is inside `<LoginContext.Provider>`
250+
4. Check that `userData` is an array with account objects
251+
252+
### Getting Username
253+
254+
```typescript
255+
// userData is an array of accounts
256+
const userName = userData[0].name.split(' ')[0]; // "Alice" from "Alice Checking"
257+
```
258+
259+
---
260+
261+
## Things to Avoid
262+
263+
### ❌ Don't Do:
264+
1. **Enable SSR** - Keep `ssr: false` in config
265+
2. **Add overdraft validation** - Intentionally missing for demos
266+
3. **Add transfer rollback logic** - Intentionally missing for demos
267+
4. **Remove mock data fallback** - Useful for development
268+
5. **Run skaffold from frontend_service/** - Must run from parent directory
269+
6. **Use SSR terminology** - This is SPA mode
270+
7. **"Fix" demo behaviors** - They're intentional features
271+
272+
### ✅ Do:
273+
1. **Read the README** before making changes
274+
2. **Check if "bugs" are intentional** (see Demo Behaviors section)
275+
3. **Test with backend services running** (via skaffold)
276+
4. **Keep state initialization in useEffect** (not during render)
277+
5. **Sync state to sessionStorage** (use existing patterns)
278+
279+
---
280+
281+
## Page Layouts
282+
283+
### Login Page (`/`)
284+
- Minimal layout (no sidebar/header)
285+
- Just the login form centered on screen
286+
- Uses separate theme from authenticated pages
287+
288+
### Authenticated Pages (`/dashboard`, `/support`, `/settings`)
289+
- Full AppLayout with:
290+
- Left sidebar (navigation)
291+
- Top header (username + notifications + logout)
292+
- Main content area (route component)
293+
- Footer (disclaimer)
294+
295+
**Layout Decision Logic**: In `root.tsx`, based on `location.pathname === '/'`
296+
297+
### Dashboard Grid Layout Structure
298+
299+
The dashboard (`/dashboard`) uses a 12-column Material-UI Grid with the following layout:
300+
301+
**Hero Section (White Background)**
302+
- Full-width white background section extending edge-to-edge
303+
- Contains "Account Summary" title and balance cards
304+
- Content has px: 48 horizontal padding to align with header and other content
305+
306+
**Grid Structure:**
307+
1. **Row 1** (4-4-4): Three balance overview cards
308+
- Total Balance
309+
- Checking Account
310+
- Savings Account
311+
312+
2. **Row 2** (4-8): Transfer card + Line chart
313+
- Transfer Funds card (4 cols)
314+
- Spending over 6 months line chart (8 cols)
315+
316+
3. **Row 3** (6-6): Two charts side by side
317+
- Spending categories pie chart (6 cols)
318+
- Account balance trends stacked bar chart (6 cols)
319+
320+
4. **Row 4** (12): Full-width Recent Transactions table
321+
322+
**Consistent Padding:**
323+
- Header: px: 48, py: 2
324+
- Dashboard hero section content: px: 48
325+
- Dashboard main content: px: 48, pb: 3
326+
- Support page: px: 48, py: 3
327+
328+
---
329+
330+
## New Relic Integration
331+
332+
The app includes New Relic Browser agent:
333+
- Script injected in `root.tsx` via `dangerouslySetInnerHTML`
334+
- Config read from environment variables
335+
- Template file: `app/nr.js`
336+
- Placeholders replaced at build time by `generate_nrjs_file.sh`
337+
338+
Errors are automatically reported to New Relic (including transfer failures).
339+
340+
---
341+
342+
## Additional Notes
343+
344+
- **Material-UI Grid**: Uses `size` prop (not `xs`/`md` - newer MUI version)
345+
- **Routing**: React Router v7 conventions (routes in `app/routes/`)
346+
- **No Redux**: State management via Context API only
347+
- **Docker**: Multi-stage build, runs on port 3000
348+
- **Demo App**: Not production-ready, missing many security features
349+
350+
---
351+
352+
## When in Doubt
353+
354+
1. Check `README.md` for detailed architecture
355+
2. Check demo behaviors section (don't "fix" intentional bugs)
356+
3. Ask user before major changes to auth/state logic
357+
4. Test in the actual Kubernetes environment (skaffold dev)

frontend_service/Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ RUN ./generate_nrjs_file.sh
2828
ENV HOST=0.0.0.0
2929
ENV PORT=3000
3030

31+
# Pre-build to optimize Vite dependencies cache
32+
# This prevents the race condition where chunks aren't ready on first page load
33+
RUN npm run build
34+
3135
# Expose the port
3236
EXPOSE 3000
3337

34-
# We don't need to run the build step for development
35-
# RUN npm run build
36-
3738
# Set the command to run the development server
3839
CMD ["npm", "run", "dev"]

0 commit comments

Comments
 (0)