@schandlergarcia/sf-web-components 1.9.66 → 1.9.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,6 @@
1
1
  # Engine Travel Command Center
2
2
 
3
- Product Requirements Document · TDX26 Demo Build
4
-
5
- **Required skills:** `command-center-builder`, `command-center-project`, `component-library`, `outer-app`
3
+ Product Requirements Document
6
4
 
7
5
  ---
8
6
 
@@ -10,28 +8,25 @@ Product Requirements Document · TDX26 Demo Build
10
8
 
11
9
  The Engine Travel Command Center is a real-time operations dashboard for corporate travel managers who use Engine (engine.com). It gives a single-screen view of every active traveler, booking, flight, policy flag, and agent interaction — built on Salesforce Data Cloud.
12
10
 
13
- It is not Engine's consumer-facing booking app. It is a personalized command center for one travel manager at one company.
14
-
15
- **Demo context:** Built live at TDX26 using Agentforce Vibes. The arc is: PRD → scaffold → data → agent → intelligence. Each build prompt maps to one beat.
11
+ **Build approach:** Incremental PRD scaffold data agent intelligence.
16
12
 
17
13
  ---
18
14
 
19
15
  ## 2. Users
20
16
 
21
17
  **Primary — Sarah Chen, Travel Manager at Acme Corp**
22
- Manages Acme's travel program: bookings, policy enforcement, exceptions, traveler monitoring. Before this dashboard she worked across Engine's booking interface, email, and Salesforce separately.
18
+ Manages Acme's travel program: bookings, policy enforcement, exceptions, traveler monitoring.
23
19
 
24
20
  **Secondary — Eva (Agentforce Agent)**
25
- Engine's Agentforce-powered AI agent. Handles traveler requests autonomously — booking changes, policy questions, itinerary lookups. Resolves ~30% of requests without human involvement. Surfaces in the dashboard via `ChatBar` (command palette).
21
+ Engine's Agentforce-powered AI agent. Handles traveler requests autonomously — booking changes, policy questions, itinerary lookups. Resolves ~30% of requests without human involvement. Surfaces via `ChatBar`.
26
22
 
27
23
  ---
28
24
 
29
25
  ## 3. Brand Tokens
30
26
 
31
- Update `src/styles/global.css` — replace the existing `--color-brand-*` palette inside the `@theme inline` block. Do not add new CSS variables or custom properties outside this block.
27
+ Update `src/styles/global.css` — replace the existing `--color-brand-*` palette inside the `@theme inline` block:
32
28
 
33
29
  ```css
34
- /* Engine teal brand palette */
35
30
  --color-brand-50: #ECFDF9;
36
31
  --color-brand-100: #D1FAF0;
37
32
  --color-brand-200: #A7F3E1;
@@ -43,185 +38,93 @@ Update `src/styles/global.css` — replace the existing `--color-brand-*` palett
43
38
  --color-brand-800: #115E59;
44
39
  --color-brand-900: #134E4A;
45
40
  --color-brand-950: #042F2E;
46
- ```
47
-
48
- Additionally, add a custom `--color-engine-savings` token for the green savings accent:
49
-
50
- ```css
51
41
  --color-engine-savings: #16A34A;
52
42
  ```
53
43
 
54
- All component styling uses `brand-*` Tailwind classes for primary UI and Tailwind built-in colors (green, amber, red) for status. No hardcoded hex values in components. No `bg-indigo-*` or raw color classes for brand elements.
55
-
56
- **Typography:** Inter (already configured as `--font-sans` in global.css). No changes needed.
44
+ Use `brand-*` Tailwind classes for brand elements. Tailwind built-in colors (green, amber, red) for status. No hardcoded hex in components.
57
45
 
58
- **Icons:** Heroicons 2 exclusively (`@heroicons/react`). No Lucide, Font Awesome, or other libraries inside command center pages.
46
+ **Typography:** Inter (already `--font-sans`). **Icons:** Heroicons 2 (`@heroicons/react`).
59
47
 
60
48
  ---
61
49
 
62
50
  ## 4. Architecture
63
51
 
64
- **Dashboard file:** `src/pages/EngineDashboard.tsx` (single file, `.tsx` — TypeScript project, React components MUST use `.tsx`)
65
-
66
- **Wiring:** `CommandCenter.tsx` imports and renders `EngineDashboard` inside the existing provider stack (`heroui-scope` → `AppThemeProvider` → `DataModeProvider` → `Toast.Provider`). Never recreate these providers in the dashboard.
67
-
68
- **Imports:** All components from `@/components/library` barrel. Theme access from `@/components/library/theme/AppThemeProvider`.
52
+ - **Dashboard file:** `src/pages/EngineDashboard.tsx`
53
+ - **Wiring:** `CommandCenter.tsx` imports and renders `EngineDashboard` inside the existing provider stack. Never recreate providers in the dashboard.
54
+ - **Imports:** Components from `@/components/library`. Theme from `@/components/library/theme/AppThemeProvider`.
69
55
 
70
56
  ---
71
57
 
72
- ## 5. Layout — Visualization-Hero Pattern
73
-
74
- This dashboard uses the **visualization-hero** layout. The live flight map is the signature element.
58
+ ## 5. Layout
75
59
 
76
- ### Structure (top to bottom)
60
+ Visualization-hero layout. Full-page scroll (no `h-screen`).
77
61
 
78
62
  ```
79
- ┌─────────────────────────────────────────────────────────────┐
80
- │ HEADER BAR (h-12, sticky)
81
- │ Engine logo + "Travel Command Center" | ChatBar | actions
82
- ├─────────────────────────────────────────────────────────────┤
83
- │ HERO MAP (h-[520px] or h-[600px], GeoMap)
84
- Full-page
85
- ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ↕ scroll
86
- │ KPI │ │ KPI │ │ KPI │ │ KPI │ ← glass
87
- overlay overlay │ overlay │ │ overlay │ overlays
88
- └─────────┘ └─────────┘ └─────────┘ └─────────┘
89
-
90
- │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ← flight │ ↕
91
- BA286 NH109 │ LH431 │ │ SQ 37 │ status │ ↕
92
- └───────┘ └───────┘ └───────┘ └───────┘ strip
93
- ├─────────────────────────────────────────────────────────────┤
94
- DATA PANELS (px-4 py-5, space-y-6, natural flow)
95
-
96
- ┌─── 1/3 ───────┐ ┌─── 2/3 ────────────────────┐
97
- Disruptions │ │ Active Travelers │ │ ↕
98
- (custom panel) (expandable cards, scroll) │ ↕
99
- └────────────────┘ └────────────────────────────┘
100
-
101
- ┌─── 1/2 ───────┐ ┌─── 1/2 ────────────────────┐
102
- │ │ Escalations │ │ Travel Spend (Monthly) │ │ ↕
103
- │ │ (ActivityCard) │ │ (ChartCard + D3Chart line) │ │ ↕
104
- │ └────────────────┘ └────────────────────────────┘ │ ↕
105
- └─────────────────────────────────────────────────────────────┘
63
+ ┌──────────────────────────────────────────────────────────────┐
64
+ │ HEADER (h-12, sticky, bg-slate-900)
65
+ │ Engine logo + "Travel Command Center" | actions + toggle
66
+ ├──────────────────────────────────────────────────────────────┤
67
+ │ HERO MAP (h-[520px], GeoMap, relative)
68
+ ┌─ glass KPI overlays (absolute top-left) ───────────────┐ │
69
+ Active Travelers | Spend MTD | Compliance | Eva Resolved
70
+ └────────────────────────────────────────────────────────┘
71
+ ┌─ flight status strip (absolute bottom) ────────────────┐
72
+ BA 286 · In Air | NH 109 · In Air | LH 431 · Delayed
73
+ └────────────────────────────────────────────────────────┘
74
+ ├──────────────────────────────────────────────────────────────┤
75
+ DATA PANELS (px-4 py-5 space-y-6)
76
+
77
+ Row 1: grid grid-cols-1 items-start gap-4 lg:grid-cols-3 │
78
+ ┌── 2/3 (lg:col-span-2) ──────┐ ┌── 1/3 ───────────────┐
79
+ Escalations (ActivityCard) │ │ Disruptions (custom) │ │
80
+ └───────────────────────────────┘ └──────────────────────┘
81
+
82
+ Row 2: grid grid-cols-1 items-start gap-4 lg:grid-cols-3
83
+ ┌── 2/3 (lg:col-span-2) ──────┐ ┌── 1/3 ───────────────┐
84
+ Active Travelers (expandable) │ │ Travel Spend (chart) │ │
85
+ └───────────────────────────────┘ └──────────────────────┘
86
+ └──────────────────────────────────────────────────────────────┘
106
87
  ```
107
88
 
108
- ### Layout Rules
89
+ ### Layout classes
109
90
 
110
- **CRITICAL: Full-page scroll, NOT viewport-locked sections.**
91
+ - **Outer:** `<div className="flex flex-col bg-slate-50 dark:bg-slate-950">`
92
+ - **Map:** `<div className="relative h-[520px]">`
93
+ - **Panels:** `<div className="px-4 py-5"><div className="space-y-6">...</div></div>`
94
+ - **Row 1:** `grid grid-cols-1 items-start gap-4 lg:grid-cols-3` — Escalations `lg:col-span-2`, Disruptions auto
95
+ - **Row 2:** `grid grid-cols-1 items-start gap-4 lg:grid-cols-3` — Travelers `lg:col-span-2`, Spend auto
111
96
 
112
- The entire dashboard scrolls as one page. Do NOT use `h-screen` or flex height constraints that lock sections to viewport.
97
+ ### Phase 1 placeholders
113
98
 
114
- - **Outer container:** `<div className="flex flex-col bg-slate-50 dark:bg-slate-950">` (NO `h-screen`)
115
- - **Hero map:** Fixed height `h-[520px]` or `h-[600px]` with `relative` positioning for glass overlays
116
- - **Data panels:** Natural flow with `px-4 py-5 space-y-6` (NO `overflow-y-auto`, NO flex height constraints)
117
- - **Row 1** - Disruptions + Travelers: `grid grid-cols-1 items-start gap-4 lg:grid-cols-3` (disruptions 1/3, travelers `lg:col-span-2`)
118
- - **Row 2** - Escalations + Chart: `grid grid-cols-1 items-start gap-4 lg:grid-cols-2`
119
- - All grids use `items-start` for different-height cards
120
-
121
- **Why full-page scroll:** Users need to see the map in context while scrolling through data. A fixed-height map that stays visible while data scrolls below creates a cramped, split-screen feeling. Full-page scroll is more natural and gives each section breathing room.
122
-
123
- ### Phase 1 Placeholder Rules
124
-
125
- **Phase 1 builds the complete layout structure** including header bar, hero map, glass KPI overlays, flight status strip, and data panels. The only "placeholders" are the **data panels** below the map.
126
-
127
- **What to build in Phase 1:**
128
- - ✅ Header bar (with logo, title, theme toggle) - **use slate scale colors, NOT text-white**
129
- - ✅ Hero map (GeoMap component with no markers/arcs/overlays props)
130
- - ✅ Glass KPI overlays (4 KPIs, hardcoded values, positioned absolutely over map)
131
- - ✅ Flight status strip (4 flights, hardcoded values, positioned at map bottom)
132
- - ✅ Data panels (BaseCard placeholders with centered text) - **these are the only placeholders**
133
-
134
- **Data panel placeholders** use `BaseCard` with centered text:
99
+ Phase 1 builds the header, map, glass overlays, and flight strip as real components. Only the 4 data panels below the map are placeholders:
135
100
 
136
101
  ```tsx
137
- // ✅ Correct data panel placeholder
138
102
  <BaseCard>
139
103
  <div className="h-48 flex items-center justify-center text-slate-400">
140
- Disruptions Panel
104
+ Escalations Panel
141
105
  </div>
142
106
  </BaseCard>
143
-
144
- // ❌ Wrong - title causes text to run together
145
- <BaseCard title="Disruptions">
146
- <div className="text-slate-400">No disruptions detected</div>
147
- </BaseCard>
148
107
  ```
149
108
 
150
- **Hero map** (render actual GeoMap component in Phase 1):
151
-
152
- ```tsx
153
- // ✅ Correct - render actual GeoMap component (empty, no data)
154
- import { GeoMap } from "@/components/library";
155
- import { useThemeMode } from "@/components/library/theme/AppThemeProvider";
156
-
157
- export default function EngineDashboard() {
158
- const { mode } = useThemeMode();
159
-
160
- return (
161
- <div className="relative h-[520px]">
162
- <GeoMap
163
- width={960}
164
- height={520}
165
- theme={mode === "dark" ? "dark" : "light"}
166
- className="h-full w-full"
167
- />
168
- </div>
169
- );
170
- }
171
- ```
172
-
173
- In Phase 1:
174
- - GeoMap component renders with NO `markers`, `arcs`, or `overlays` props (these are GeoMap data props for Phase 2+)
175
- - GeoMap will render the base world map (land, sphere, graticule) even without data - this is NOT a placeholder, it's the actual map component
176
- - Glass KPI overlays and flight status strip ARE built in Phase 1 (as separate `<div>` elements positioned absolutely over the map)
177
- - Uses `useThemeMode()` to get dark/light mode for theme prop
178
- - **Verify:** You should see a blue world map (dark theme) or gray world map (light theme) with glass overlays on top
179
-
180
- // ❌ Wrong - wrapped in BaseCard
181
- <div className="relative h-[520px]">
182
- <BaseCard>
183
- <GeoMap ... />
184
- </BaseCard>
185
- </div>
186
-
187
- // ❌ Wrong - text placeholder instead of GeoMap component
188
- <div className="relative h-[520px]">
189
- <div className="flex h-full items-center justify-center bg-slate-100 dark:bg-slate-900">
190
- <span className="text-slate-400">Hero Map (GeoMap)</span>
191
- </div>
192
- </div>
193
- ```
194
-
195
- All data panel placeholders use: BaseCard, no title, centered text, `h-48`, `text-slate-400`.
196
-
197
- Hero map uses: actual GeoMap component (no markers/arcs/overlays in Phase 1), direct render, fills hero container.
109
+ The GeoMap renders the base world map with no data props. Glass overlays and flight strip use hardcoded values.
198
110
 
199
111
  ---
200
112
 
201
113
  ## 6. Header
202
114
 
203
- Compact `h-12` sticky header with dark background (`bg-slate-900 dark:bg-slate-950`).
204
-
205
- | Position | Content |
206
- |----------|---------|
207
- | Left | Engine logo (small square icon with `GlobeAltIcon` in `bg-brand-600`) + "ENGINE" wordmark + separator + "Travel Command Center" |
208
- | Right | `ChatBar` (Eva) + notification bell (with pending count badge) + theme toggle (sun/moon) |
115
+ Compact `h-12` sticky header (`bg-slate-900 dark:bg-slate-950`).
209
116
 
210
- The `ChatBar` replaces any FAB or sliding panel. It opens inline as a command palette overlay.
117
+ | Left | Right |
118
+ |------|-------|
119
+ | Engine logo (`GlobeAltIcon` in `bg-brand-600` square) + "ENGINE" wordmark + separator + "Travel Command Center" | ChatBar (Phase 4) + notification bell (badge count) + theme toggle (sun/moon) |
211
120
 
212
121
  ---
213
122
 
214
123
  ## 7. Hero Map
215
124
 
216
- **Component:** `GeoMap` (from `@/components/library`)
217
-
218
- **Phase 1:** Render GeoMap with NO data props (no markers/arcs/overlays)
219
- **Phase 2:** Add markers, arcs, and overlays from sample data to show where travelers are
125
+ **Component:** `GeoMap` from `@/components/library`
220
126
 
221
127
  ```tsx
222
- import { MAP_MARKERS, MAP_ARCS, MAP_OVERLAYS } from "@/data/engine-sample-data";
223
-
224
- // Phase 2 - with map data
225
128
  <GeoMap
226
129
  width={960}
227
130
  height={520}
@@ -234,52 +137,27 @@ import { MAP_MARKERS, MAP_ARCS, MAP_OVERLAYS } from "@/data/engine-sample-data";
234
137
  />
235
138
  ```
236
139
 
237
- **Markers:** One per city (origin and destination). Each marker: `{ id, lon, lat, label, active: true }`. Shows where travelers are located.
140
+ - **Markers:** One per city. `{ id, lon, lat, label, active: true }`
141
+ - **Arcs:** One per flight route. `{ id, from: [lon, lat], to: [lon, lat], progress: 0–1, danger: boolean }`. `danger: true` on disrupted routes.
142
+ - **Overlays:** Weather zones. `{ id, center: [lon, lat], radius: number }`
143
+ - **Phase 1:** Render GeoMap with no data props (map renders base world automatically)
144
+ - **Phase 2:** Add `MAP_MARKERS`, `MAP_ARCS`, `MAP_OVERLAYS` from `@/data/engine-sample-data`
238
145
 
239
- **Arcs:** One per active flight route. Each arc: `{ id, from: [lon, lat], to: [lon, lat], progress: 0–1 }`. Set `danger: true` on disrupted routes (delayed 60+ min or grounded). The `progress` value places an animated pulsing dot showing the flight's current position along the great circle arc.
146
+ **Glass KPI overlays** 4 pills, `absolute left-3 top-3`:
147
+ Active Travelers (count), Spend MTD (`fmtK()`), Compliance %, Eva Resolved (count + "resolved").
148
+ Style: `bg-black/40 backdrop-blur-md border border-white/10 rounded-lg px-3 py-1.5`
240
149
 
241
- **Overlays:** Weather/disruption zones as pulsing circles. Each overlay: `{ id, center: [lon, lat], radius: number }`.
242
-
243
- **Glass KPI overlays:** Four pills floating `absolute left-3 top-3` on the map:
244
- - Active Travelers (count)
245
- - Spend MTD (formatted with `fmtK()`)
246
- - Compliance %
247
- - Eva Resolved (count + "resolved")
248
-
249
- Each pill: `bg-black/40 backdrop-blur-md border border-white/10 rounded-lg px-3 py-1.5` with white text and icon.
250
-
251
- **Flight status strip:** Floating `absolute bottom-3 left-3 right-3`, horizontal scroll. One pill per active flight showing flight number + status chip (On Time = green, Delayed = amber, Grounded/Boarding = contextual). Same glass styling as KPI overlays.
150
+ **Flight status strip** `absolute bottom-3 left-3 right-3`, horizontal scroll. One pill per flight: flight number + status chip (green=On Time, amber=Delayed, contextual=Boarding). Same glass styling.
252
151
 
253
152
  ---
254
153
 
255
154
  ## 8. Data Panels
256
155
 
257
- **CRITICAL: Panel titles MUST match PRD exactly, even if data export has different name.**
258
-
259
- For example: Panel titled "Escalations" uses data exported as `EVA_ACTIONS` or `ESCALATION_CARDS` (both are aliases). The PRD panel title takes precedence over data export names.
260
-
261
- ### 8a. Disruptions Panel (1/3 width)
262
-
263
- Custom inline component inside a `BaseCard`. Shows only flights that are delayed 60+ min or grounded.
264
-
265
- Each disruption card:
266
- - Severity dot (rose for grounded, amber for delayed) + flight number + severity label + delay minutes
267
- - Route + affected traveler name
268
- - Reason text
269
- - Eva action line with `SparklesIcon` showing what Eva is doing about it
156
+ 4 panels in 2 rows. Sample data imported from `src/data/engine-sample-data.js`.
270
157
 
271
- ### 8b. Active Travelers (2/3 width)
158
+ ### 8a. Escalations (Row 1, 2/3 width)
272
159
 
273
- `BaseCard` with `maxBodyHeight={420}` for internal scroll. Expandable traveler cards.
274
-
275
- Each traveler row:
276
- - `Avatar` (initials) + name + department + origin → destination
277
- - `UIChip` for policy status (success = compliant, warning = exception)
278
- - Click to expand: 4-col grid showing Flight, Hotel, Return date, Destination
279
-
280
- ### 8c. Escalations (1/2 width)
281
-
282
- **CRITICAL: ActivityCard has no card styling by default. Must wrap in BaseCard for visible card background.**
160
+ ActivityCard wrapped in BaseCard:
283
161
 
284
162
  ```tsx
285
163
  <BaseCard>
@@ -290,30 +168,35 @@ Each traveler row:
290
168
  </BaseCard>
291
169
  ```
292
170
 
293
- **Data source:** Import `ESCALATION_CARDS` from sample data (alias of `EVA_ACTIONS`)
171
+ Each escalation: title, subtitle, status (`"working"` | `"pending"` | `"complete"`), timestamp.
172
+
173
+ ### 8b. Disruptions (Row 1, 1/3 width)
174
+
175
+ Custom inline component in BaseCard. Shows flights delayed 60+ min or grounded.
176
+
177
+ Each disruption card:
178
+ - Severity dot (rose=grounded, amber=delayed) + flight number + delay minutes
179
+ - Route + traveler name
180
+ - Reason text
181
+ - Eva action line with `SparklesIcon`
182
+
183
+ Data: `DISRUPTION_CARDS` from sample data.
294
184
 
295
- Each escalation has:
296
- - Title (issue description)
297
- - Subtitle (details + context)
298
- - Status: `"working"` (Eva is handling), `"pending"` (needs review), or `"complete"` (resolved)
299
- - Timestamp
185
+ ### 8c. Active Travelers (Row 2, 2/3 width)
300
186
 
301
- Examples from sample data:
302
- - "Processing approval for Omar Hassan" - subtitle: "Paris trip over budget · escalated to manager" (status: pending)
303
- - "Monitoring weather delay for Elena Rodriguez" - subtitle: "AF 99 · CDG arrival delayed 45 min · No action yet" (status: working)
304
- - "Rebooked cancelled flight for Priya Patel" - subtitle: "LH 431 → LH 433 · Same fare class" (status: complete)
187
+ BaseCard with `maxBodyHeight={420}`. Expandable traveler cards.
305
188
 
306
- ### 8d. Monthly Spend Trend (1/2 width)
189
+ Each row: `Avatar` (initials) + name + department + origin → destination + `UIChip` (compliant/exception).
190
+ Expand: 4-col grid — Flight, Hotel, Return, Destination.
307
191
 
308
- `ChartCard` wrapping a `D3Chart` with `D3ChartTemplates.groupedBarChart` (lineChart doesn't support categorical x-axis).
192
+ Data: `TRAVELER_CARDS` from sample data.
309
193
 
310
- **CRITICAL: Use this exact code structure:**
194
+ ### 8d. Monthly Spend Trend (Row 2, 1/3 width)
311
195
 
312
196
  ```tsx
313
- // Transform data to chart format
314
- const spendChartData = useDataSource({
315
- sample: MONTHLY_SPEND.map(m => ({ x: m.month, spend: m.amount })),
316
- live: []
197
+ const spendChartData = useDataSource({
198
+ sample: MONTHLY_SPEND.map(m => ({ x: m.month, spend: m.amount })),
199
+ live: [],
317
200
  });
318
201
 
319
202
  <ChartCard
@@ -338,153 +221,72 @@ const spendChartData = useDataSource({
338
221
  />
339
222
  ```
340
223
 
341
- **Data source:** Import `MONTHLY_SPEND` from sample data, transform to chart format
342
-
343
- **Requirements:**
344
- - X-axis: month names (Oct through Mar) - categorical
345
- - Y-axis: spend amount in dollars (will show as thousands: 98000, 128000, etc.)
346
- - Height: 320px
347
- - Bar color: Engine teal (#5BC8C8)
348
- - Bar radius: 6 for rounded corners
349
- - **Data transformation:** map `{ month, amount }` to `{ x, spend }` format inline
350
- - responsive={true}
351
-
352
- **Why this chart:** Shows spend trends over time so travel managers can spot anomalies, budget overruns, or seasonal patterns. Using bars instead of line because D3 lineChart requires numeric x-axis.
353
-
354
- **That's it!** Only 4 panels total: Disruptions, Active Travelers, Escalations, and Monthly Spend Trend.
355
-
356
224
  ---
357
225
 
358
- ## 9. Eva — ChatBar
226
+ ## 9. Eva — ChatBar (Phase 4)
359
227
 
360
- Eva surfaces as a `ChatBar` in the header. Not a FAB. Not a sliding panel. Not a `ChatPanel` in the grid.
228
+ ChatBar in the header. Not a FAB or sliding panel.
361
229
 
362
- ```jsx
230
+ ```tsx
363
231
  <ChatBar
364
232
  title="Eva"
365
233
  placeholder="Ask about travelers, bookings, policy, spend…"
366
- suggestions={suggestions}
234
+ suggestions={CHAT_SUGGESTIONS}
367
235
  onSend={handleChat}
368
236
  />
369
237
  ```
370
238
 
371
- **Starter suggestions (3–5):**
372
- - "Who's traveling internationally right now?"
373
- - "Show bookings pending approval"
374
- - "What has Eva resolved today?"
375
- - "Travelers returning this week"
239
+ Suggestions: "Who's traveling internationally right now?", "Show bookings pending approval", "What has Eva resolved today?", "Travelers returning this week"
376
240
 
377
- **Agent responses:** Return structured `components` arrays for data (MetricCard, DataTable, StatusCard) — never markdown tables in text content.
378
-
379
- **Handler:** Define `handleChat` and `CHAT_SUGGESTIONS` at module scope (outside the component body) so they can be shared if an "open in tab" feature is added later.
241
+ Define `handleChat` and `CHAT_SUGGESTIONS` at module scope.
380
242
 
381
243
  ---
382
244
 
383
- ## 10. Salesforce Signals (Phase 4 Only)
384
-
385
- **⚠️ These are added in Phase 4, NOT Phase 1.** Phase 1 has only the Engine logo and "Travel Command Center" title.
245
+ ## 10. Salesforce Signals (Phase 4)
386
246
 
387
- Subtle, contextual indicators — like "Sent from iPhone", not promotional banners.
247
+ Subtle indicators, not banners.
388
248
 
389
- | Signal | Location | Implementation | Phase |
390
- |--------|----------|----------------|-------|
391
- | "View in Salesforce" | Traveler expanded view, booking rows | Micro-link, muted text | Phase 4 |
392
- | "Salesforce updated" | After rebook/approve actions | `toast()` with success tone | Phase 4 |
393
- | "Powered by Agentforce" | ChatBar title or subtitle area | Small badge/chip | Phase 4 |
249
+ | Signal | Location |
250
+ |--------|----------|
251
+ | "View in Salesforce" | Traveler expanded view, booking rows (micro-link, muted text) |
252
+ | "Salesforce updated" | After rebook/approve actions (`toast()`) |
253
+ | "Powered by Agentforce" | ChatBar subtitle area (small badge) |
394
254
 
395
255
  ---
396
256
 
397
257
  ## 11. Dark Mode
398
258
 
399
- Mandatory on every element. The dashboard must work in both light and dark mode with no visual bugs.
400
-
401
- - Use the standard dark mode pairs from the builder rules (bg-white/dark:bg-slate-900, etc.)
402
- - The GeoMap has built-in dark/light themes — pass `theme={mode === "dark" ? "dark" : "light"}`
403
- - Glass overlays use `bg-black/40 backdrop-blur-md` which works in both modes
404
- - Custom inline components (disruption cards, flight chips) must include `dark:` variants on every color class
405
- - Never use `text-black` or `text-white` directly — use the slate scale
406
- - Theme toggle button in the header (sun/moon icon)
259
+ Every element supports light and dark. GeoMap: `theme={mode === "dark" ? "dark" : "light"}`. Glass overlays work in both modes. Use slate scale (no `text-white` or `text-black`). Theme toggle in header.
407
260
 
408
261
  ---
409
262
 
410
263
  ## 12. Data Model
411
264
 
412
- **Traveler** — `id`, `name`, `department`, `destination`, `origin`, `hotel`, `flight`, `return`, `status`, `policyStatus` (compliant | exception)
413
-
414
- **Flight** — `id`, `flight` (number), `route`, `dep` (time), `status` (On Time | Delayed | Boarding | In Air | Landed), `traveler`, `delayMin`
415
-
416
- **Disruption** — `id`, `flight`, `route`, `traveler`, `severity` (grounded | delayed), `delayMin`, `reason`, `evaAction`
417
-
418
- **Map Coordinates** — City name → `[lon, lat]` lookup object. Markers derived from coordinates. Arcs derived from flight origin/destination pairs.
419
-
420
- **Booking** — `id`, `traveler`, `type`, `destination`, `dates`, `cost`, `status` (Confirmed | Pending approval), `policy` (In policy | Over budget | Exception granted)
421
-
422
- **Policy Item** — `id`, `title`, `description`, `status` (operational | degraded), `timestamp`
423
-
424
- **Escalation** — `id`, `title`, `subtitle`, `status` (complete | working | pending), `timestamp`
425
-
426
- **Monthly Spend** — `{ month: string, amount: number }` array. Six months of travel spend data (Oct through Mar). Amounts in dollars, typically $98K-$156K range.
427
-
428
- **Sample data:** 8–10 travelers, 8 flights, 4 disruptions, 8 bookings, 5 policy items, 8 escalations, 6 months of spend. All deterministic (no `Math.random()`). Include realistic names, routes, dollar amounts, and a mix of all status types.
265
+ - **Traveler** — `id`, `name`, `department`, `destination`, `origin`, `hotel`, `flight`, `return`, `policyStatus` (compliant | exception)
266
+ - **Flight** — `id`, `flight`, `route`, `dep`, `status` (On Time | Delayed | Boarding | In Air | Landed), `traveler`, `delayMin`
267
+ - **Disruption** — `id`, `flight`, `route`, `traveler`, `severity` (grounded | delayed), `delayMin`, `reason`, `evaAction`
268
+ - **Escalation** — `id`, `title`, `subtitle`, `status` (complete | working | pending), `timestamp`
269
+ - **Monthly Spend** — `{ month, amount }` array, 6 months (Oct–Mar), $98K–$156K range
270
+ - **Sample data:** Pre-built in `src/data/engine-sample-data.js`. 8 travelers, 8 flights, 4 disruptions, 8 escalations, 6 months spend. All deterministic.
429
271
 
430
272
  ---
431
273
 
432
274
  ## 13. Build Prompts
433
275
 
434
- **Build Methodology:** 4-phase incremental process (Layout → Components → Data → Agent). Each phase has a self-contained instruction file in `.a4drules/phases/` with code templates and exact imports.
435
-
436
- ---
276
+ Build in 4 incremental phases.
437
277
 
438
278
  ### Phase 1: Layout & Structure
439
279
 
440
- > Read `.a4drules/phases/phase-1-layout.md` and follow the code template.
441
- >
442
- > Scaffold the Engine Travel Command Center skeleton with header, hero map, glass KPI overlays, flight status strip, and 4 placeholder data panels.
443
-
444
- ---
280
+ > Scaffold the Engine Travel Command Center skeleton. Build the visualization-hero layout from section 5 with the header, hero map, glass KPI overlays, flight status strip, and placeholder cards for the data panels.
445
281
 
446
282
  ### Phase 2: Components & Sample Data
447
283
 
448
- > Read `.a4drules/phases/phase-2-components.md` and follow the instructions.
449
- >
450
- > Replace placeholders with library components. Import data from `src/data/engine-sample-data.js`. Add map data (markers, arcs, overlays). Build the 4 data panels: Disruptions, Active Travelers, Escalations, Monthly Spend Trend.
451
-
452
- ---
284
+ > Replace the placeholders with real components and wire up the sample data. Build the 4 data panels from section 8 — Escalations, Disruptions, Active Travelers, and Monthly Spend Trend. Add map markers, arcs, and overlays from the sample data so we can see where travelers are.
453
285
 
454
286
  ### Phase 3: Real Data Integration
455
287
 
456
- > Read `.a4drules/phases/phase-3-live-data.md` and follow the instructions.
457
- >
458
- > Connect to live Salesforce data via GraphQL. UI stays identical to Phase 2.
459
-
460
- ---
288
+ > Connect the dashboard to live Salesforce data using GraphQL. Read the sample data file to see which fields are needed, then build queries and hooks for each object. The UI should stay identical — just swap the data source.
461
289
 
462
290
  ### Phase 4: Agentforce Integration
463
291
 
464
- > Read `.a4drules/phases/phase-4-agent.md` and follow the instructions.
465
- >
466
- > Add Eva ChatBar to header. Add Salesforce signals throughout.
467
-
468
- ---
469
-
470
- ## 14. What NOT to Do
471
-
472
- These are explicit anti-patterns. If any prompt output includes these, it must be corrected:
473
-
474
- - Do not use `react-simple-maps`, Recharts, or any charting library other than the built-in `D3Chart` + `D3ChartTemplates`
475
- - Do not use Lucide icons, Font Awesome, or any icon library other than Heroicons 2
476
- - Do not import from `src/components/ui/` (shadcn) — use `@/components/library` exclusively
477
- - Do not use `cn()` helper — that belongs to the outer app
478
- - Do not recreate `AppThemeProvider`, `DataModeProvider`, or `Toast.Provider` — `CommandCenter.tsx` provides them
479
- - Do not build a FAB or sliding chat panel — use `ChatBar` in the header
480
- - Do not hardcode hex color values in component JSX — use `brand-*` Tailwind classes and Tailwind built-in colors for status
481
- - Do not use `bg-indigo-*` for brand — use `brand-*`
482
- - Do not use `text-black` or `text-white` — use the slate scale
483
- - Do not put more than 4 KPIs in a row
484
- - Do not squeeze the map into a grid column — it must be full-width hero
485
- - Do not wrap GeoMap in ChartCard — render it directly
486
- - Do not use `Math.random()` in sample data
487
- - Do not skip dark mode on any visible element
488
- - Do not use inline `style={{}}` for layout except the flex properties on the hero/panel containers
489
- - Do not put `ChatPanel` in the dashboard grid
490
- - Do not use `position: fixed` without `createPortal` to `document.body`
292
+ > Add Eva to the header as a ChatBar. Add subtle Salesforce signals throughout — "View in Salesforce" links, success toasts, "Powered by Agentforce" badge.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schandlergarcia/sf-web-components",
3
- "version": "1.9.66",
3
+ "version": "1.9.68",
4
4
  "description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",