@schandlergarcia/sf-web-components 1.9.62 → 1.9.64
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.
- package/.a4drules/features/command-center-dashboard-rule.md +20 -46
- package/.a4drules/features/engine-dashboard-rule.md +36 -288
- package/.a4drules/features/phase2-data-pattern.md +8 -159
- package/.a4drules/features/pre-code-checklist.md +16 -205
- package/.a4drules/phases/phase-1-layout.md +187 -0
- package/.a4drules/phases/phase-2-components.md +176 -0
- package/.a4drules/phases/phase-3-live-data.md +85 -0
- package/.a4drules/phases/phase-4-agent.md +73 -0
- package/.a4drules/skills/command-center-builder/SKILL.md +6 -30
- package/.a4drules/skills/command-center-builder/completion-checklist.md +3 -29
- package/.a4drules/skills/command-center-builder/improved-build-process.md +20 -331
- package/.a4drules/skills/command-center-builder/page-layout.md +4 -2
- package/.a4drules/skills/command-center-guide/SKILL.md +23 -257
- package/.a4drules/skills/command-center-project/SKILL.md +1 -1
- package/CHANGELOG.md +47 -0
- package/data/engine-command-center-prd.md +31 -33
- package/data/engine-sample-data.js +20 -8
- package/package.json +1 -1
|
@@ -1,59 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
paths:
|
|
3
|
-
- "**/pages/*.jsx"
|
|
4
3
|
- "**/pages/*.tsx"
|
|
5
4
|
- "**/components/workspace/CommandCenter.tsx"
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
# Command Center Dashboard Rules
|
|
7
|
+
# Command Center Dashboard Rules
|
|
9
8
|
|
|
10
|
-
These rules
|
|
9
|
+
These rules apply to all dashboard files. For Engine-specific rules, see `engine-dashboard-rule.md`.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
## Core Constraints
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
1. Dashboard files: `.tsx` in `src/pages/` — never `.jsx`, never `src/components/pages/`
|
|
14
|
+
2. Import components from `@/components/library` only — no shadcn (`@/components/ui/`)
|
|
15
|
+
3. Charts: `ChartCard` + `D3Chart` or `GeoMap` only — no Recharts, Chart.js, or custom SVG
|
|
16
|
+
4. Icons: Heroicons (`@heroicons/react`) only — no Lucide, no inline SVGs
|
|
17
|
+
5. Colors: Slate scale — no `text-white`, `text-black`, `bg-black`
|
|
18
|
+
6. Data: All data via `useDataSource({ sample, live })`
|
|
19
|
+
7. Layout: Single scrollable page — no multi-tab navigation, no `<nav>` inside dashboards
|
|
20
|
+
8. Providers: Never recreate `AppThemeProvider`, `DataModeProvider`, or `Toast.Provider` — `CommandCenter.tsx` provides them
|
|
21
|
+
9. DO NOT run `npm run dev`, `npm run validate:dashboard`, or `npm run build` during builds
|
|
22
|
+
10. DO NOT `npm install` any packages — everything needed is already installed
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
## Wiring
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
After creating a dashboard, update all 3 files:
|
|
27
|
+
1. `CommandCenter.tsx` — import and render your dashboard
|
|
28
|
+
2. `Home.tsx` — render `CommandCenter`
|
|
29
|
+
3. `routes.tsx` — set `Home` as index route
|
|
19
30
|
|
|
20
|
-
|
|
31
|
+
## Component API
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
1. **File extension MUST be `.tsx`** — This is a TypeScript project. All React components MUST use `.tsx` extension, never `.jsx`. Dashboard files go in `src/pages/` (NOT `src/components/pages/`). All type definitions are available from the component library.
|
|
25
|
-
|
|
26
|
-
2. **Use ONLY library components** from `@/components/library` for cards, charts, tables, lists. Never hand-roll HTML cards (`<div className="bg-white border rounded...">`).
|
|
27
|
-
|
|
28
|
-
3. **Charts: ONLY `ChartCard` + `D3Chart` or `GeoMap`** — Do NOT use Recharts, Chart.js, or any third-party chart library. Do NOT `npm install` any chart or map packages (react-simple-maps, recharts, chart.js, nivo, etc.). Everything you need is in the library.
|
|
29
|
-
|
|
30
|
-
4. **Maps: use `GeoMap`** from `@/components/library` — Do NOT install react-simple-maps or any other map library.
|
|
31
|
-
|
|
32
|
-
5. **No shadcn imports** (`@/components/ui/`) — use library equivalents. No Lucide icons — use Heroicons (`@heroicons/react`). No `cn()` utility.
|
|
33
|
-
|
|
34
|
-
6. **No dashboard-level navigation** — no `<nav>`, no tab bars, no `useState` for switching between page sections. Build a single scrollable page. The app shell handles navigation.
|
|
35
|
-
|
|
36
|
-
7. **WidgetCard does NOT accept children** — pass content via `sections` prop: `<WidgetCard sections={[{ id: "main", content: <div>...</div> }]} />`. Children are silently ignored.
|
|
37
|
-
|
|
38
|
-
8. **ListCard avatar** — do NOT pass initials strings (treated as image URL). Omit `avatar` to auto-generate initials from `title`/`name`.
|
|
39
|
-
|
|
40
|
-
9. **BaseCard applies `p-4` padding** — do NOT add extra `p-5`/`p-6` to WidgetCard `header` or section `content`.
|
|
41
|
-
|
|
42
|
-
10. **No forbidden colors** — never use `text-white`, `text-black`, `bg-black`. Use slate scale: `text-slate-50`, `text-slate-900`, `bg-slate-900`.
|
|
43
|
-
|
|
44
|
-
11. **`useDataSource`** is required — wire all data through `useDataSource({ sample, live })` for sample/live mode.
|
|
45
|
-
|
|
46
|
-
12. **Run `npm run validate:dashboard`** before reporting done — fix ALL errors, zero tolerance. Never dismiss errors as "justified". The validator MUST show zero errors before the dashboard is considered complete.
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
cd force-app/main/default/webapplications/reactapp4
|
|
50
|
-
npm run validate:dashboard
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
If errors are reported, you MUST fix them by switching to library components, correct colors, or proper imports. Do not proceed until the validator shows zero errors.
|
|
54
|
-
|
|
55
|
-
13. **Do NOT `npm install` any packages** for dashboard work. The component library and existing dependencies have everything needed.
|
|
56
|
-
|
|
57
|
-
14. **Heroicon names** — common correct names: `PaperAirplaneIcon` (not PlaneIcon), `BuildingOfficeIcon` (not HotelIcon), `BanknotesIcon` (not MoneyIcon), `ExclamationTriangleIcon` (not AlertIcon), `UserIcon` (not PersonIcon).
|
|
58
|
-
|
|
59
|
-
15. **Wire the dashboard as the home page.** After creating your dashboard and updating `CommandCenter.tsx`, you MUST also update `src/pages/Home.tsx` to render `CommandCenter` (replace any search interface with `import CommandCenter from "@/components/workspace/CommandCenter"; export default function HomePage() { return <CommandCenter />; }`), and update `src/routes.tsx` to set `Home` as the index route and move `Search` to `/search`. The dashboard must be the first thing users see at `/`.
|
|
33
|
+
For full component props and data shapes, read `.a4drules/skills/component-library/SKILL.md`.
|
|
@@ -4,306 +4,54 @@ paths:
|
|
|
4
4
|
- "**/pages/Engine*.tsx"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Engine
|
|
7
|
+
# Engine Dashboard — Auto-Loaded Rules
|
|
8
8
|
|
|
9
|
-
These rules
|
|
9
|
+
These rules load automatically when editing Engine dashboard files. For full build instructions, use the phase files in `.a4drules/phases/`.
|
|
10
10
|
|
|
11
11
|
## Source of Truth
|
|
12
12
|
|
|
13
|
-
**The PRD is law
|
|
13
|
+
**The PRD is law.** `engine-command-center-prd.md` is the complete specification. If anything conflicts with the PRD, the PRD wins.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Non-Negotiable Constraints
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
1. **File:** `.tsx` extension, located in `src/pages/`
|
|
18
|
+
2. **Imports:** ONLY from `@/components/library` and `@heroicons/react` — no shadcn (`@/components/ui/`), no Lucide, no Recharts
|
|
19
|
+
3. **Colors:** Slate scale only — `text-slate-50` not `text-white`, `bg-slate-900` not `bg-black`. Exception: `bg-black/40` with opacity is OK for glass overlays
|
|
20
|
+
4. **Layout:** Full-page scroll (no `h-screen`), visualization-hero pattern with full-width map
|
|
21
|
+
5. **Data:** All data via `useDataSource({ sample, live })` — sample data imported from `src/data/engine-sample-data.js`
|
|
22
|
+
6. **Dark mode:** Every custom element needs `dark:` variants
|
|
23
|
+
7. **DO NOT** run `npm run dev`, `npm run validate:dashboard`, or `npm run build` during builds
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
2. **Phase 2: Components + Sample Data** — Replace data panel placeholders with real library components + sample data AND add map data
|
|
21
|
-
- **CRITICAL:** Sample data file already exists at `src/data/engine-sample-data.js`
|
|
22
|
-
- **DO NOT create a new data file** — just import from the existing one
|
|
23
|
-
- Import dashboard-ready derivatives (MAP_MARKERS, MAP_ARCS, MAP_OVERLAYS, TRAVELER_CARDS, ESCALATION_CARDS, MONTHLY_SPEND)
|
|
24
|
-
- DO NOT define sample data inline in the dashboard — causes file truncation
|
|
25
|
-
- **FOLLOW THE EXACT CODE EXAMPLES in PRD Section 7 (map) and Section 8c/8d (panels)** - copy the code blocks as shown
|
|
26
|
-
- **Map data:** Add markers, arcs, overlays to GeoMap to show where travelers are (see PRD Section 7)
|
|
27
|
-
- **Panel titles:** "Disruptions", "Active Travelers", "Escalations", "Travel Spend"
|
|
28
|
-
- **Escalations panel:** ActivityCard must be wrapped in BaseCard for visible card styling
|
|
29
|
-
- **Chart:** Line chart showing monthly spend trend (see PRD Section 8d code block for exact options)
|
|
30
|
-
- **DO NOT run validation or dev server** — phase is complete after wiring files
|
|
31
|
-
3. **Phase 3: Real Data** — Connect to Salesforce, keep UI identical to Phase 2
|
|
32
|
-
4. **Phase 4: Agent** — Add Eva ChatBar integration
|
|
25
|
+
## Phase Build Order
|
|
33
26
|
|
|
34
|
-
|
|
27
|
+
| Phase | File | What it covers |
|
|
28
|
+
|-------|------|----------------|
|
|
29
|
+
| 1 | `.a4drules/phases/phase-1-layout.md` | Header, hero map, glass overlays, flight strip, placeholder panels |
|
|
30
|
+
| 2 | `.a4drules/phases/phase-2-components.md` | Library components, sample data, map data, charts |
|
|
31
|
+
| 3 | `.a4drules/phases/phase-3-live-data.md` | GraphQL hooks, live Salesforce data |
|
|
32
|
+
| 4 | `.a4drules/phases/phase-4-agent.md` | Eva ChatBar, Salesforce signals |
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
- ✅ Header bar with logo, title, and theme toggle (use slate scale colors, NO text-white)
|
|
38
|
-
- ✅ Hero map (GeoMap component with NO markers/arcs/overlays PROPS passed)
|
|
39
|
-
- ✅ Glass KPI overlays (4 hardcoded values, positioned absolutely over map)
|
|
40
|
-
- ✅ Flight status strip (4 hardcoded flights, positioned at map bottom)
|
|
41
|
-
- ✅ Data panel placeholders (BaseCard with centered text) - **ONLY these are placeholders**
|
|
34
|
+
Complete each phase fully before starting the next. Read the relevant phase file for detailed instructions and code templates.
|
|
42
35
|
|
|
43
|
-
|
|
36
|
+
## Wiring Checklist
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
<BaseCard>
|
|
47
|
-
<div className="h-48 flex items-center justify-center text-slate-400">
|
|
48
|
-
Disruptions Panel
|
|
49
|
-
</div>
|
|
50
|
-
</BaseCard>
|
|
51
|
-
```
|
|
38
|
+
After creating or updating `EngineDashboard.tsx`:
|
|
52
39
|
|
|
53
|
-
|
|
40
|
+
1. `CommandCenter.tsx` imports `EngineDashboard` (not `BlankDashboard`)
|
|
41
|
+
2. `Home.tsx` renders `CommandCenter`
|
|
42
|
+
3. `routes.tsx` has `Home` as index route, `Search` at `/search`
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
import { GeoMap } from "@/components/library";
|
|
57
|
-
import { useThemeMode } from "@/components/library/theme/AppThemeProvider";
|
|
44
|
+
## Component Quick Reference
|
|
58
45
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
```
|
|
46
|
+
| Need | Use |
|
|
47
|
+
|------|-----|
|
|
48
|
+
| KPI number | `MetricCard` |
|
|
49
|
+
| Data table | `TableCard` |
|
|
50
|
+
| Item list | `ListCard` |
|
|
51
|
+
| Activity feed | `ActivityCard` (wrap in `BaseCard` for card styling) |
|
|
52
|
+
| Chart | `ChartCard` + `D3Chart` with `D3ChartTemplates` |
|
|
53
|
+
| Map | `GeoMap` (direct, not wrapped in ChartCard) |
|
|
54
|
+
| Status items | `StatusCard` |
|
|
55
|
+
| Multi-section | `WidgetCard` |
|
|
74
56
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Hero map in Phase 1: actual GeoMap component with NO `markers`/`arcs`/`overlays` props passed (these are GeoMap data props for Phase 2+). The base world map (land, sphere, graticule) will render even with no data. Glass KPI overlays and flight status strip ARE built in Phase 1 as separate `<div>` elements positioned absolutely over the map - these provide visual confirmation the map area is rendering. GeoMap is NOT wrapped in BaseCard.
|
|
78
|
-
|
|
79
|
-
**Verify the map renders:** After building, check that you can see the world map base layer (blue land on dark theme, gray land on light theme). If the map area appears blank, check:
|
|
80
|
-
- Container has fixed height (`className="relative h-[520px]"`)
|
|
81
|
-
- GeoMap has `className="h-full w-full"`
|
|
82
|
-
- No console errors from GeoMap component
|
|
83
|
-
|
|
84
|
-
**DO NOT:**
|
|
85
|
-
- Mix phases (don't add sample data in Phase 1, don't add Eva in Phase 2, etc.)
|
|
86
|
-
- Run `npm run dev` or `npm run validate:dashboard` (wastes turns, not required)
|
|
87
|
-
- Use BaseCard titles in Phase 1 placeholders (causes text to run together)
|
|
88
|
-
- Use `h-screen` or viewport-locked layout (full-page scroll required)
|
|
89
|
-
|
|
90
|
-
### Phase 3: Real Data Integration
|
|
91
|
-
|
|
92
|
-
**CRITICAL:** You MUST explicitly use the Salesforce GraphQL skills by name. Declarative listing doesn't work - use imperative commands.
|
|
93
|
-
|
|
94
|
-
**Goal:** Connect dashboard to live Salesforce data. No toggle needed - dashboard shows live data only.
|
|
95
|
-
|
|
96
|
-
**Key insight:** The sample data file (`src/data/engine-sample-data.js`) already uses real Salesforce field names (Trip__c, Flight__c, Contact, etc.). Read the file header comment to understand the object schema.
|
|
97
|
-
|
|
98
|
-
**Custom objects used:**
|
|
99
|
-
- Contact (travelers, with custom fields: Home_Airport__c, Travel_Policy_Tier__c, etc.)
|
|
100
|
-
- Trip__c (origin, destination, dates, cost, policy status)
|
|
101
|
-
- Flight__c (flight number, airports, status, delay, traveler lookup)
|
|
102
|
-
- Booking__c (upcoming reservations)
|
|
103
|
-
- Disruption__c (delays, cancellations, severity)
|
|
104
|
-
- Rebooking_Action__c (Eva activity log)
|
|
105
|
-
- Travel_Policy__c (policy rules and status)
|
|
106
|
-
|
|
107
|
-
**Implementation steps (FOLLOW EXACTLY):**
|
|
108
|
-
|
|
109
|
-
1. **Read sample data file** (`src/data/engine-sample-data.js`) to understand which Salesforce fields are needed (e.g., Trip__c has Origin_City__c, Contact has FirstName, etc.)
|
|
110
|
-
|
|
111
|
-
2. **Use the Salesforce GraphQL skills** to implement queries and hooks:
|
|
112
|
-
|
|
113
|
-
- Use `exploring-webapp-graphql-schema` skill to look up each object
|
|
114
|
-
- Say: "Use the exploring-webapp-graphql-schema skill to look up Trip__c"
|
|
115
|
-
- The skill reads from schema.graphql (already checked into the repo)
|
|
116
|
-
|
|
117
|
-
- Use `generating-webapp-graphql-read-query` skill to create queries
|
|
118
|
-
- Say: "Use the generating-webapp-graphql-read-query skill to create a query for Trip__c"
|
|
119
|
-
- The skill generates properly typed GraphQL code with @optional directives
|
|
120
|
-
|
|
121
|
-
- Use `using-webapp-graphql` skill to implement hooks
|
|
122
|
-
- Say: "Use the using-webapp-graphql skill to create a useTravelers hook"
|
|
123
|
-
- The skill creates hooks that return { data, loading, error }
|
|
124
|
-
|
|
125
|
-
3. **Update useDataSource calls** to use live data:
|
|
126
|
-
- Change: `useDataSource({ sample: TRAVELER_CARDS })`
|
|
127
|
-
- To: `useDataSource({ sample: TRAVELER_CARDS, live: liveTravelers ?? [] })`
|
|
128
|
-
|
|
129
|
-
4. **No data mode toggle** - dashboard always shows live data (or falls back to sample on error)
|
|
130
|
-
|
|
131
|
-
**Key insight:** The schema.graphql file is pre-built and checked into the repo. GraphQL skills and tooling work out of the box without any schema generation.
|
|
132
|
-
|
|
133
|
-
**Example pattern:**
|
|
134
|
-
|
|
135
|
-
```tsx
|
|
136
|
-
// Phase 2 (sample data only)
|
|
137
|
-
const travelers = useDataSource({ sample: TRAVELER_CARDS, live: [] });
|
|
138
|
-
|
|
139
|
-
// Phase 3 (live data with sample fallback on error)
|
|
140
|
-
const { data: liveTravelers, loading, error } = useTravelers();
|
|
141
|
-
const travelers = useDataSource({
|
|
142
|
-
sample: TRAVELER_CARDS, // Used as fallback if live data fails
|
|
143
|
-
live: liveTravelers ?? [] // Primary data source
|
|
144
|
-
});
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
The `useDataSource` hook automatically uses `live` data when available, falling back to `sample` only on error. No toggle UI needed.
|
|
148
|
-
|
|
149
|
-
**DO NOT:**
|
|
150
|
-
- Ask the user about object names - they're in the sample data file
|
|
151
|
-
- Create object metadata - objects already exist in org
|
|
152
|
-
- Change field names in queries - use exact names from sample data
|
|
153
|
-
- Modify UI components - only change data sources
|
|
154
|
-
- Add DataModeToggle - Phase 3 uses live data only (sample data is fallback for errors)
|
|
155
|
-
- Panic if schema introspection fails - queries still work fine (see troubleshooting guide below)
|
|
156
|
-
- List skills declaratively - use imperative commands ("Use the X skill to...")
|
|
157
|
-
|
|
158
|
-
**Troubleshooting:** If you encounter GraphQL schema introspection failures, see `.a4drules/troubleshooting/graphql-introspection-failure.md` for the complete workaround pattern.
|
|
159
|
-
|
|
160
|
-
## Phase Completion (NO VALIDATION REQUIRED)
|
|
161
|
-
|
|
162
|
-
After wiring the dashboard into CommandCenter, Home, and routes, the phase is complete.
|
|
163
|
-
|
|
164
|
-
**🚫 CRITICAL: DO NOT run `npm run dev` or `npm run validate:dashboard`**
|
|
165
|
-
|
|
166
|
-
These commands are NOT required for phase completion. Do NOT execute them. The phase is complete after wiring the files.
|
|
167
|
-
|
|
168
|
-
## File Requirements
|
|
169
|
-
|
|
170
|
-
- **Extension:** `.tsx` (TypeScript) — NEVER `.jsx`
|
|
171
|
-
- **Location:** `src/pages/EngineDashboard.tsx` (NOT `src/components/pages/`)
|
|
172
|
-
- **Imports:** ONLY from `@/components/library` — never shadcn, never Lucide, never Recharts
|
|
173
|
-
|
|
174
|
-
## Layout Pattern: Visualization-Hero with Full-Page Scroll
|
|
175
|
-
|
|
176
|
-
The Engine dashboard uses the **visualization-hero** layout (see PRD section 5). This means:
|
|
177
|
-
|
|
178
|
-
1. **Hero map:** Full-width, fixed height (`h-[520px]`), GeoMap with glass overlays and flight status strip
|
|
179
|
-
2. **Data panels below:** Natural flow with `px-4 py-5` (NO overflow constraints)
|
|
180
|
-
3. **Full-page scroll:** Entire dashboard scrolls naturally (NO `h-screen` on outer container)
|
|
181
|
-
|
|
182
|
-
**DO NOT:**
|
|
183
|
-
- Put the map in a 1/3 or 1/2 grid column (it's hero, not sidebar)
|
|
184
|
-
- Use `h-screen` or viewport-locked layout (full-page scroll required)
|
|
185
|
-
- Use `overflow-y-auto` or flex height constraints on data panels
|
|
186
|
-
- Wrap GeoMap in ChartCard (render directly)
|
|
187
|
-
- Skip the glass KPI overlays or flight status strip
|
|
188
|
-
- Make the map too small (minimum 400px height)
|
|
189
|
-
|
|
190
|
-
## Component Selection
|
|
191
|
-
|
|
192
|
-
Every section of the dashboard MUST use a library component. No hand-rolled HTML cards:
|
|
193
|
-
|
|
194
|
-
| Content | Use | NOT |
|
|
195
|
-
|---------|-----|-----|
|
|
196
|
-
| KPI number | `MetricCard` | `<div className="bg-white ...">` |
|
|
197
|
-
| Data table | `TableCard` | `<table>` HTML |
|
|
198
|
-
| Item list | `ListCard` | Custom `.map()` divs |
|
|
199
|
-
| Activity log | `ActivityCard` | Custom feed markup |
|
|
200
|
-
| Chart | `ChartCard` + `D3Chart` | Recharts/Chart.js/custom SVG |
|
|
201
|
-
| Map | `GeoMap` (direct) | react-simple-maps |
|
|
202
|
-
| Status items | `StatusCard` | Custom status badges |
|
|
203
|
-
| Multi-section panel | `WidgetCard` | Nested divs |
|
|
204
|
-
| Expandable content | `WidgetCard` (single section) | Hand-rolled collapse logic |
|
|
205
|
-
|
|
206
|
-
## Engine Brand Colors
|
|
207
|
-
|
|
208
|
-
Update `src/styles/global.css` with Engine teal palette (PRD section 3). Use `engine-*` and `brand-*` Tailwind classes, never hardcoded hex values.
|
|
209
|
-
|
|
210
|
-
## Dark Mode (MANDATORY)
|
|
211
|
-
|
|
212
|
-
Every visible element MUST work in both light and dark mode. Test both before reporting complete.
|
|
213
|
-
|
|
214
|
-
- GeoMap: pass `theme={mode === "dark" ? "dark" : "light"}`
|
|
215
|
-
- Glass overlays: `bg-black/40 backdrop-blur-md` (works in both modes)
|
|
216
|
-
- Text: use slate scale, never `text-black` or `text-white`
|
|
217
|
-
- All custom elements: add `dark:` variants
|
|
218
|
-
|
|
219
|
-
## Eva Integration (Phase 4 Only)
|
|
220
|
-
|
|
221
|
-
Eva is a `ChatBar` in the header. NOT a FAB. NOT a ChatPanel in the grid. NOT a sliding panel.
|
|
222
|
-
|
|
223
|
-
```tsx
|
|
224
|
-
<ChatBar
|
|
225
|
-
title="Eva"
|
|
226
|
-
placeholder="Ask Eva..."
|
|
227
|
-
suggestions={CHAT_SUGGESTIONS}
|
|
228
|
-
onSend={handleChat}
|
|
229
|
-
/>
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Data Mode (Sample vs Live)
|
|
233
|
-
|
|
234
|
-
Every component must work in both data modes:
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
// ✅ Correct
|
|
238
|
-
const SAMPLE_TRAVELERS = [...]; // module scope
|
|
239
|
-
const travelers = useDataSource({ sample: SAMPLE_TRAVELERS, live: liveTravelers });
|
|
240
|
-
|
|
241
|
-
// ❌ Wrong — no mode switching
|
|
242
|
-
const travelers = [...]; // always uses same data
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Wiring Steps (REQUIRED)
|
|
246
|
-
|
|
247
|
-
After creating `EngineDashboard.tsx`, you MUST:
|
|
248
|
-
|
|
249
|
-
1. Update `src/components/workspace/CommandCenter.tsx`:
|
|
250
|
-
```tsx
|
|
251
|
-
import EngineDashboard from "../../pages/EngineDashboard";
|
|
252
|
-
// ... render <EngineDashboard />
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
2. Update `src/pages/Home.tsx`:
|
|
256
|
-
```tsx
|
|
257
|
-
import CommandCenter from "@/components/workspace/CommandCenter";
|
|
258
|
-
export default function HomePage() { return <CommandCenter />; }
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
3. Update `src/routes.tsx`:
|
|
262
|
-
```tsx
|
|
263
|
-
{ index: true, element: <Home />, handle: { showInNavigation: true, label: 'Dashboard' } }
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Verify all three files are updated before reporting complete.
|
|
267
|
-
|
|
268
|
-
## Pre-Completion Checklist
|
|
269
|
-
|
|
270
|
-
Before reporting ANY phase complete, verify ALL of these:
|
|
271
|
-
|
|
272
|
-
- [ ] Validator shows zero errors (`npm run validate:dashboard`)
|
|
273
|
-
- [ ] File is `.tsx` not `.jsx`
|
|
274
|
-
- [ ] All cards are library components (MetricCard, ListCard, etc.)
|
|
275
|
-
- [ ] No hand-rolled HTML cards (`<div className="bg-white border ...">`)
|
|
276
|
-
- [ ] No shadcn imports (`@/components/ui/`)
|
|
277
|
-
- [ ] No Lucide icons (use Heroicons)
|
|
278
|
-
- [ ] No chart libraries (use D3Chart/GeoMap)
|
|
279
|
-
- [ ] GeoMap rendered directly, not wrapped in ChartCard
|
|
280
|
-
- [ ] Dark mode works on all elements
|
|
281
|
-
- [ ] `useDataSource` used for all data
|
|
282
|
-
- [ ] Sample data is module-scope constants
|
|
283
|
-
- [ ] CommandCenter.tsx, Home.tsx, and routes.tsx are updated
|
|
284
|
-
- [ ] Dev server starts without errors (`npm run dev`)
|
|
285
|
-
|
|
286
|
-
## What Makes This Dashboard Unique
|
|
287
|
-
|
|
288
|
-
The Engine dashboard's signature elements (must be present):
|
|
289
|
-
|
|
290
|
-
1. **Hero map** — Full-width GeoMap with animated flight arcs, weather overlays, glass KPI pills, and flight status strip
|
|
291
|
-
2. **Glass overlays** — Floating KPIs and flight chips with `bg-black/40 backdrop-blur-md`
|
|
292
|
-
3. **Engine brand** — Teal color palette throughout
|
|
293
|
-
4. **Eva integration** — ChatBar in header for AI queries
|
|
294
|
-
5. **Disruptions panel** — Custom inline component showing severity dots and Eva actions
|
|
295
|
-
|
|
296
|
-
These elements distinguish the Engine dashboard from generic dashboards. They must all be present and functional.
|
|
297
|
-
|
|
298
|
-
## Anti-Patterns (NEVER DO THESE)
|
|
299
|
-
|
|
300
|
-
- Creating BlankDashboard.tsx or GenericDashboard.tsx (name is EngineDashboard.tsx)
|
|
301
|
-
- Multi-tab layout with content swapping (build one scrollable page)
|
|
302
|
-
- `<nav>` or header bar inside the dashboard (AppLayout handles navigation)
|
|
303
|
-
- Map in a sidebar grid (it's hero — full width)
|
|
304
|
-
- **Using `h-screen` or viewport-locked layout** (full-page scroll required)
|
|
305
|
-
- More than 4 KPIs in a row
|
|
306
|
-
- Using `Math.random()` in sample data
|
|
307
|
-
- **Running `npm run dev` or `npm run validate:dashboard`** (not required, wastes turns)
|
|
308
|
-
- Reporting phase complete before wiring the dashboard into the app
|
|
309
|
-
- Mixing phases (adding sample data in Phase 1, adding Eva in Phase 2, etc.)
|
|
57
|
+
For full component API, read `.a4drules/skills/component-library/SKILL.md`.
|
|
@@ -1,166 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
paths:
|
|
3
|
-
- "**/pages/*.tsx"
|
|
4
|
-
- "**/data/*.ts"
|
|
5
|
-
---
|
|
1
|
+
# Phase 2: Sample Data Pattern
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
For complete Phase 2 instructions, see `.a4drules/phases/phase-2-components.md`.
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
## Key Rule
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
The sample data file already exists at `src/data/engine-sample-data.js`. **DO NOT create a new data file.** Import from the existing one.
|
|
12
8
|
|
|
13
|
-
##
|
|
9
|
+
## Available exports
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
- Dashboard file becomes 500+ lines
|
|
17
|
-
- File gets truncated during writing
|
|
18
|
-
- Unclosed JSX tags and syntax errors
|
|
19
|
-
- Agent has to retry multiple times
|
|
11
|
+
**Base records:** `TRAVELERS`, `TRIPS`, `FLIGHTS`, `HOTELS`, `DISRUPTIONS`, `BOOKINGS`, `REBOOKING_ACTIONS`, `TRAVEL_POLICIES`, `ACCOUNT`, `MONTHLY_SPEND`
|
|
20
12
|
|
|
21
|
-
|
|
13
|
+
**Dashboard-ready derivatives:** `MAP_MARKERS`, `MAP_ARCS`, `MAP_OVERLAYS`, `FLIGHT_STATUS_LIST`, `TRAVELER_CARDS`, `DISRUPTION_CARDS`, `ESCALATION_CARDS`, `EVA_ACTIONS`, `BOOKING_ROWS`, `POLICY_ITEMS`, `DESTINATION_CHART_DATA`, `SPEND_CHART_DATA`, `METRICS`
|
|
22
14
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
### Data File Already Exists
|
|
26
|
-
|
|
27
|
-
The file `src/data/engine-sample-data.js` contains all sample data as exported constants:
|
|
28
|
-
|
|
29
|
-
```javascript
|
|
30
|
-
// src/data/engine-sample-data.js
|
|
31
|
-
// THIS FILE ALREADY EXISTS - DO NOT CREATE IT
|
|
32
|
-
|
|
33
|
-
// Sample data exports (already defined):
|
|
34
|
-
export const TRAVELERS = [...]; // 8 travelers with Contact fields
|
|
35
|
-
export const TRIPS = [...]; // 8 trips with Trip__c fields
|
|
36
|
-
export const FLIGHTS = [...]; // 8 flights with Flight__c fields
|
|
37
|
-
export const HOTELS = [...]; // 8 hotels with Reservation fields
|
|
38
|
-
export const DISRUPTIONS = [...]; // 4 disruptions
|
|
39
|
-
export const BOOKINGS = [...]; // 8 upcoming bookings
|
|
40
|
-
export const REBOOKING_ACTIONS = [...]; // 8 Eva actions
|
|
41
|
-
export const TRAVEL_POLICIES = [...]; // 5 policy items
|
|
42
|
-
export const MONTHLY_SPEND = [...]; // 6 months of spend
|
|
43
|
-
export const ACCOUNT = {...}; // Account stats
|
|
44
|
-
|
|
45
|
-
// Dashboard-ready derivatives (already computed):
|
|
46
|
-
export const MAP_MARKERS = [...]; // For GeoMap markers prop
|
|
47
|
-
export const MAP_ARCS = [...]; // For GeoMap arcs prop
|
|
48
|
-
export const MAP_OVERLAYS = [...]; // For GeoMap overlays prop
|
|
49
|
-
export const FLIGHT_STATUS_LIST = [...]; // For flight status strip
|
|
50
|
-
export const TRAVELER_CARDS = [...]; // For traveler ListCard
|
|
51
|
-
export const DISRUPTION_CARDS = [...]; // For disruptions panel
|
|
52
|
-
export const EVA_ACTIONS = [...]; // For ActivityCard
|
|
53
|
-
export const BOOKING_ROWS = [...]; // For TableCard
|
|
54
|
-
export const POLICY_ITEMS = [...]; // For StatusCard
|
|
55
|
-
export const DESTINATION_CHART_DATA = [...]; // For destination chart
|
|
56
|
-
export const SPEND_CHART_DATA = [...]; // For spend chart
|
|
57
|
-
export const METRICS = {...}; // Computed KPIs
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
This file is ~370 lines and contains all sample data you need.
|
|
61
|
-
|
|
62
|
-
### Import Into Dashboard
|
|
63
|
-
|
|
64
|
-
In `src/pages/EngineDashboard.tsx`, import the pre-existing data:
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
// src/pages/EngineDashboard.tsx
|
|
68
|
-
import React from "react";
|
|
69
|
-
import { BaseCard, ListCard, ActivityCard, ChartCard, TableCard, StatusCard, D3Chart, GeoMap } from "@/components/library";
|
|
70
|
-
import {
|
|
71
|
-
MAP_MARKERS,
|
|
72
|
-
MAP_ARCS,
|
|
73
|
-
MAP_OVERLAYS,
|
|
74
|
-
FLIGHT_STATUS_LIST,
|
|
75
|
-
TRAVELER_CARDS,
|
|
76
|
-
DISRUPTION_CARDS,
|
|
77
|
-
EVA_ACTIONS,
|
|
78
|
-
BOOKING_ROWS,
|
|
79
|
-
POLICY_ITEMS,
|
|
80
|
-
DESTINATION_CHART_DATA,
|
|
81
|
-
SPEND_CHART_DATA,
|
|
82
|
-
METRICS
|
|
83
|
-
} from "@/data/engine-sample-data";
|
|
84
|
-
|
|
85
|
-
export default function EngineDashboard() {
|
|
86
|
-
return (
|
|
87
|
-
<div className="flex h-screen flex-col bg-slate-50 dark:bg-slate-950">
|
|
88
|
-
{/* Header - use METRICS for KPIs */}
|
|
89
|
-
|
|
90
|
-
{/* Hero Map - use MAP_MARKERS, MAP_ARCS, MAP_OVERLAYS */}
|
|
91
|
-
<GeoMap markers={MAP_MARKERS} arcs={MAP_ARCS} overlays={MAP_OVERLAYS} />
|
|
92
|
-
|
|
93
|
-
{/* Data Panels */}
|
|
94
|
-
<div className="px-4 py-5 space-y-6">
|
|
95
|
-
{/* Disruptions - use DISRUPTION_CARDS */}
|
|
96
|
-
{/* Active Travelers - use TRAVELER_CARDS */}
|
|
97
|
-
{/* Eva Activity - use EVA_ACTIONS */}
|
|
98
|
-
<ActivityCard title="Eva Activity" actions={EVA_ACTIONS} />
|
|
99
|
-
|
|
100
|
-
{/* Charts - use DESTINATION_CHART_DATA, SPEND_CHART_DATA */}
|
|
101
|
-
{/* Bookings - use BOOKING_ROWS */}
|
|
102
|
-
<TableCard items={BOOKING_ROWS} />
|
|
103
|
-
|
|
104
|
-
{/* Policy - use POLICY_ITEMS */}
|
|
105
|
-
<StatusCard items={POLICY_ITEMS} />
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Dashboard file stays ~150-200 lines because data is imported.
|
|
113
|
-
|
|
114
|
-
## Phase 2 Workflow
|
|
115
|
-
|
|
116
|
-
**DO NOT create the data file** — it already exists. Just:
|
|
117
|
-
|
|
118
|
-
1. Read `src/data/engine-sample-data.js` to understand available exports
|
|
119
|
-
2. Import the dashboard-ready derivatives into `src/pages/EngineDashboard.tsx`
|
|
120
|
-
3. Replace BaseCard placeholders with library components using imported data
|
|
121
|
-
|
|
122
|
-
## Benefits
|
|
123
|
-
|
|
124
|
-
- ✅ Dashboard file stays small (no truncation)
|
|
125
|
-
- ✅ Data file already prepared and tested
|
|
126
|
-
- ✅ Clean separation of concerns
|
|
127
|
-
- ✅ Easy to switch to live data in Phase 3 (just change imports)
|
|
128
|
-
- ✅ Faster Phase 2 completion (no data creation needed)
|
|
129
|
-
|
|
130
|
-
## Common Mistakes
|
|
131
|
-
|
|
132
|
-
❌ **Creating a new data file:**
|
|
133
|
-
```bash
|
|
134
|
-
# WRONG - file already exists
|
|
135
|
-
Write src/data/engine-sample-data.ts
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
❌ **Defining data inline in dashboard:**
|
|
139
|
-
```typescript
|
|
140
|
-
export default function EngineDashboard() {
|
|
141
|
-
const travelers = [
|
|
142
|
-
{ id: "1", name: "Maya Rodriguez", ... }, // 500 more lines
|
|
143
|
-
];
|
|
144
|
-
// File gets truncated here!
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
✅ **Importing from existing file:**
|
|
148
|
-
```typescript
|
|
149
|
-
import { TRAVELER_CARDS, EVA_ACTIONS } from "@/data/engine-sample-data";
|
|
150
|
-
|
|
151
|
-
export default function EngineDashboard() {
|
|
152
|
-
// Use imported data
|
|
153
|
-
<ListCard items={TRAVELER_CARDS} />
|
|
154
|
-
<ActivityCard actions={EVA_ACTIONS} />
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Complete Phase 2 Workflow
|
|
159
|
-
|
|
160
|
-
1. **Read** `src/data/engine-sample-data.js` (understand exports)
|
|
161
|
-
2. **Import** dashboard-ready derivatives into `src/pages/EngineDashboard.tsx`
|
|
162
|
-
3. **Replace** BaseCard placeholders with library components using imported data
|
|
163
|
-
4. **Run** validator (`npm run validate:dashboard`)
|
|
164
|
-
5. **Test** in browser
|
|
165
|
-
|
|
166
|
-
This pattern prevents truncation and keeps code clean.
|
|
15
|
+
All derivatives are computed from the base records — not hardcoded separately.
|