@schandlergarcia/sf-web-components 2.0.0 → 2.1.0

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.
@@ -0,0 +1,234 @@
1
+ @import '@heroui/styles';
2
+
3
+ @layer base {
4
+ html,
5
+ body,
6
+ #root {
7
+ @apply min-h-screen;
8
+ }
9
+
10
+ body {
11
+ @apply antialiased bg-white;
12
+ }
13
+ }
14
+
15
+ @import 'tw-animate-css';
16
+ @import 'shadcn/tailwind.css';
17
+
18
+ @custom-variant dark (&:is(.dark *));
19
+
20
+ @source "../components/library";
21
+ @source "../components/pages";
22
+
23
+ @theme inline {
24
+ --color-background: var(--background);
25
+ --color-foreground: var(--foreground);
26
+ --color-card: var(--card);
27
+ --color-card-foreground: var(--card-foreground);
28
+ --color-popover: var(--popover);
29
+ --color-popover-foreground: var(--popover-foreground);
30
+ --color-primary: var(--primary);
31
+ --color-primary-foreground: var(--primary-foreground);
32
+ --color-secondary: var(--secondary);
33
+ --color-secondary-foreground: var(--secondary-foreground);
34
+ --color-muted: var(--muted);
35
+ --color-muted-foreground: var(--muted-foreground);
36
+ --color-accent: var(--accent);
37
+ --color-accent-foreground: var(--accent-foreground);
38
+ --color-destructive: var(--destructive);
39
+ --color-destructive-foreground: var(--destructive-foreground);
40
+ --color-border: var(--border);
41
+ --color-input: var(--input);
42
+ --color-ring: var(--ring);
43
+ --color-chart-1: var(--chart-1);
44
+ --color-chart-2: var(--chart-2);
45
+ --color-chart-3: var(--chart-3);
46
+ --color-chart-4: var(--chart-4);
47
+ --color-chart-5: var(--chart-5);
48
+ --radius-sm: calc(var(--radius) - 4px);
49
+ --radius-md: calc(var(--radius) - 2px);
50
+ --radius-lg: var(--radius);
51
+ --radius-xl: calc(var(--radius) + 4px);
52
+ --color-sidebar: var(--sidebar);
53
+ --color-sidebar-foreground: var(--sidebar-foreground);
54
+ --color-sidebar-primary: var(--sidebar-primary);
55
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
56
+ --color-sidebar-accent: var(--sidebar-accent);
57
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
58
+ --color-sidebar-border: var(--sidebar-border);
59
+ --color-sidebar-ring: var(--sidebar-ring);
60
+
61
+ /* Engine brand palette — official guidelines */
62
+ --color-engine-black: #0D1117;
63
+ --color-engine-cyan: #7DCBD9;
64
+ --color-engine-green: #1E9D6D;
65
+ --color-engine-blue: #157DE5;
66
+ --color-engine-orange: #FD4B23;
67
+ --color-engine-amber: #FFB200;
68
+ --color-engine-bg: #F3F3F4;
69
+ --color-engine-border: #B0B1B3;
70
+ --color-engine-text: #0D1117;
71
+ --color-engine-muted: #616368;
72
+ --color-engine-label: #B0B1B3;
73
+
74
+ /* Engine Cyan brand ramp */
75
+ --color-brand-50: #F0FAFB;
76
+ --color-brand-100: #D9F2F5;
77
+ --color-brand-200: #B3E5EB;
78
+ --color-brand-300: #7DCBD9;
79
+ --color-brand-400: #5BB8CA;
80
+ --color-brand-500: #3AA0B5;
81
+ --color-brand-600: #2D849A;
82
+ --color-brand-700: #266B7E;
83
+ --color-brand-800: #235768;
84
+ --color-brand-900: #1F4858;
85
+ --color-brand-950: #112E3A;
86
+
87
+ --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
88
+ --font-mono: 'JetBrains Mono', ui-monospace, monospace;
89
+
90
+ --radius-pill: 9999px;
91
+ --radius-card: 10px;
92
+ }
93
+
94
+ :root {
95
+ --radius: 0.625rem;
96
+ --background: oklch(1 0 0);
97
+ --foreground: oklch(0.145 0 0);
98
+ --card: oklch(1 0 0);
99
+ --card-foreground: oklch(0.145 0 0);
100
+ --popover: oklch(1 0 0);
101
+ --popover-foreground: oklch(0.145 0 0);
102
+ --primary: oklch(0.205 0 0);
103
+ --primary-foreground: oklch(0.985 0 0);
104
+ --secondary: oklch(0.97 0 0);
105
+ --secondary-foreground: oklch(0.205 0 0);
106
+ --muted: oklch(0.97 0 0);
107
+ --muted-foreground: oklch(0.556 0 0);
108
+ --accent: oklch(0.97 0 0);
109
+ --accent-foreground: oklch(0.205 0 0);
110
+ --destructive: oklch(0.577 0.245 27.325);
111
+ --border: oklch(0.922 0 0);
112
+ --input: oklch(0.922 0 0);
113
+ --ring: oklch(0.708 0 0);
114
+ --chart-1: oklch(0.646 0.222 41.116);
115
+ --chart-2: oklch(0.6 0.118 184.704);
116
+ --chart-3: oklch(0.398 0.07 227.392);
117
+ --chart-4: oklch(0.828 0.189 84.429);
118
+ --chart-5: oklch(0.769 0.188 70.08);
119
+ --sidebar: oklch(0.985 0 0);
120
+ --sidebar-foreground: oklch(0.145 0 0);
121
+ --sidebar-primary: oklch(0.205 0 0);
122
+ --sidebar-primary-foreground: oklch(0.985 0 0);
123
+ --sidebar-accent: oklch(0.97 0 0);
124
+ --sidebar-accent-foreground: oklch(0.205 0 0);
125
+ --sidebar-border: oklch(0.922 0 0);
126
+ --sidebar-ring: oklch(0.708 0 0);
127
+ }
128
+
129
+ .dark {
130
+ --background: oklch(0.145 0 0);
131
+ --foreground: oklch(0.985 0 0);
132
+ --card: oklch(0.205 0 0);
133
+ --card-foreground: oklch(0.985 0 0);
134
+ --popover: oklch(0.205 0 0);
135
+ --popover-foreground: oklch(0.985 0 0);
136
+ --primary: oklch(0.922 0 0);
137
+ --primary-foreground: oklch(0.205 0 0);
138
+ --secondary: oklch(0.269 0 0);
139
+ --secondary-foreground: oklch(0.985 0 0);
140
+ --muted: oklch(0.269 0 0);
141
+ --muted-foreground: oklch(0.708 0 0);
142
+ --accent: oklch(0.269 0 0);
143
+ --accent-foreground: oklch(0.985 0 0);
144
+ --destructive: oklch(0.704 0.191 22.216);
145
+ --border: oklch(1 0 0 / 10%);
146
+ --input: oklch(1 0 0 / 15%);
147
+ --ring: oklch(0.556 0 0);
148
+ --chart-1: oklch(0.488 0.243 264.376);
149
+ --chart-2: oklch(0.696 0.17 162.48);
150
+ --chart-3: oklch(0.769 0.188 70.08);
151
+ --chart-4: oklch(0.627 0.265 303.9);
152
+ --chart-5: oklch(0.645 0.246 16.439);
153
+ --sidebar: oklch(0.205 0 0);
154
+ --sidebar-foreground: oklch(0.985 0 0);
155
+ --sidebar-primary: oklch(0.488 0.243 264.376);
156
+ --sidebar-primary-foreground: oklch(0.985 0 0);
157
+ --sidebar-accent: oklch(0.269 0 0);
158
+ --sidebar-accent-foreground: oklch(0.985 0 0);
159
+ --sidebar-border: oklch(1 0 0 / 10%);
160
+ --sidebar-ring: oklch(0.556 0 0);
161
+ }
162
+
163
+ @layer base {
164
+ * {
165
+ @apply border-border outline-ring/50;
166
+ }
167
+ body {
168
+ @apply bg-background text-foreground;
169
+ }
170
+ }
171
+
172
+ /*
173
+ * Restore HeroUI theme variables inside the Command Center scope.
174
+ * Uses Engine brand colors: Cyan #7DCBD9 as secondary, Orange-Red #FD4B23 as danger.
175
+ */
176
+ .heroui-scope {
177
+ --primary: #0D1117;
178
+ --primary-foreground: oklch(0.9911 0 0);
179
+ --secondary: #7DCBD9;
180
+ --secondary-foreground: #0D1117;
181
+ --success: #1E9D6D;
182
+ --success-foreground: oklch(0.9911 0 0);
183
+ --warning: #FFB200;
184
+ --warning-foreground: #0D1117;
185
+ --danger: #FD4B23;
186
+ --danger-foreground: oklch(0.9911 0 0);
187
+
188
+ --muted: oklch(0.5517 0.0138 285.94);
189
+ --accent: oklch(0.6204 0.195 253.83);
190
+ --accent-foreground: oklch(0.9911 0 0);
191
+ --background: #F3F3F4;
192
+ --foreground: #0D1117;
193
+ --default: oklch(94% 0.001 286.375);
194
+ --default-foreground: #0D1117;
195
+ --border: #B0B1B3;
196
+ --separator: oklch(92% 0.004 286.32);
197
+ --segment: oklch(100% 0 0);
198
+ --segment-foreground: #0D1117;
199
+ --surface: oklch(100% 0 0);
200
+ --surface-foreground: #0D1117;
201
+ --overlay: oklch(100% 0 0);
202
+ --overlay-foreground: #0D1117;
203
+ --focus: #157DE5;
204
+ --link: #0D1117;
205
+ }
206
+
207
+ /* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
208
+ body > .fixed.inset-x-0.rounded-2xl {
209
+ left: 1.5rem !important;
210
+ right: 1.5rem !important;
211
+ }
212
+
213
+ .dark .heroui-scope,
214
+ .heroui-scope.dark {
215
+ --muted: oklch(70.5% 0.015 286.067);
216
+ --background: oklch(12% 0.005 285.823);
217
+ --foreground: oklch(0.9911 0 0);
218
+ --default: oklch(27.4% 0.006 286.033);
219
+ --default-foreground: oklch(0.9911 0 0);
220
+ --border: oklch(28% 0.006 286.033);
221
+ --separator: oklch(25% 0.006 286.033);
222
+ --segment: oklch(0.3964 0.01 285.93);
223
+ --segment-foreground: oklch(0.9911 0 0);
224
+ --surface: oklch(0.2103 0.0059 285.89);
225
+ --surface-foreground: oklch(0.9911 0 0);
226
+ --overlay: oklch(0.2103 0.0059 285.89);
227
+ --overlay-foreground: oklch(0.9911 0 0);
228
+ --warning: oklch(0.8203 0.1388 76.34);
229
+ --warning-foreground: #0D1117;
230
+ --danger: oklch(0.594 0.1967 24.63);
231
+ --danger-foreground: oklch(0.9911 0 0);
232
+ --focus: #157DE5;
233
+ --link: oklch(0.9911 0 0);
234
+ }
@@ -0,0 +1,292 @@
1
+ """
2
+ Generated schema for Engine Travel Command Center
3
+ Source: src/data/engine-sample-data.js field names
4
+ Note: This is a minimal schema for GraphQL tooling when introspection is broken
5
+ """
6
+
7
+ schema {
8
+ query: Query
9
+ }
10
+
11
+ type Query {
12
+ uiapi: UIAPI!
13
+ }
14
+
15
+ type UIAPI {
16
+ query: UIAPIQuery!
17
+ }
18
+
19
+ type UIAPIQuery {
20
+ Contact(first: Int, after: String, where: ContactFilter): ContactConnection
21
+ Trip__c(first: Int, after: String, where: Trip__cFilter): Trip__cConnection
22
+ Flight__c(first: Int, after: String, where: Flight__cFilter): Flight__cConnection
23
+ Booking__c(first: Int, after: String, where: Booking__cFilter): Booking__cConnection
24
+ Disruption__c(first: Int, after: String, where: Disruption__cFilter): Disruption__cConnection
25
+ Rebooking_Action__c(first: Int, after: String, where: Rebooking_Action__cFilter): Rebooking_Action__cConnection
26
+ Travel_Policy__c(first: Int, after: String, where: Travel_Policy__cFilter): Travel_Policy__cConnection
27
+ }
28
+
29
+ # Field value wrappers for FLS
30
+ type FieldValueString {
31
+ value: String
32
+ displayValue: String
33
+ }
34
+
35
+ type FieldValueFloat {
36
+ value: Float
37
+ displayValue: String
38
+ }
39
+
40
+ type FieldValueBoolean {
41
+ value: Boolean
42
+ displayValue: String
43
+ }
44
+
45
+ type FieldValueID {
46
+ value: ID
47
+ displayValue: String
48
+ }
49
+
50
+ # Contact (Travelers)
51
+ type Contact {
52
+ Id: ID!
53
+ FirstName: FieldValueString
54
+ LastName: FieldValueString
55
+ Department: FieldValueString
56
+ Home_Airport__c: FieldValueString
57
+ Travel_Policy_Tier__c: FieldValueString
58
+ Is_Active_Traveler__c: FieldValueBoolean
59
+ Role__c: FieldValueString
60
+ }
61
+
62
+ type ContactEdge {
63
+ node: Contact!
64
+ cursor: String!
65
+ }
66
+
67
+ type ContactConnection {
68
+ edges: [ContactEdge!]!
69
+ pageInfo: PageInfo!
70
+ totalCount: Int
71
+ }
72
+
73
+ input ContactFilter {
74
+ Id: IDFilter
75
+ FirstName: StringFilter
76
+ LastName: StringFilter
77
+ Department: StringFilter
78
+ }
79
+
80
+ # Trip__c
81
+ type Trip__c {
82
+ Id: ID!
83
+ Trip_Name__c: FieldValueString
84
+ Contact__c: FieldValueString
85
+ Origin_City__c: FieldValueString
86
+ Origin_Airport__c: FieldValueString
87
+ Destination_City__c: FieldValueString
88
+ Destination_Airport__c: FieldValueString
89
+ Start_Date__c: FieldValueString
90
+ End_Date__c: FieldValueString
91
+ Status__c: FieldValueString
92
+ Total_Cost__c: FieldValueFloat
93
+ In_Policy__c: FieldValueBoolean
94
+ Has_Disruption__c: FieldValueBoolean
95
+ }
96
+
97
+ type Trip__cEdge {
98
+ node: Trip__c!
99
+ cursor: String!
100
+ }
101
+
102
+ type Trip__cConnection {
103
+ edges: [Trip__cEdge!]!
104
+ pageInfo: PageInfo!
105
+ totalCount: Int
106
+ }
107
+
108
+ input Trip__cFilter {
109
+ Id: IDFilter
110
+ Trip_Name__c: StringFilter
111
+ Status__c: StringFilter
112
+ }
113
+
114
+ # Flight__c
115
+ type Flight__c {
116
+ Id: ID!
117
+ Flight_Number__c: FieldValueString
118
+ Airline__c: FieldValueString
119
+ Departure_Airport__c: FieldValueString
120
+ Departure_City__c: FieldValueString
121
+ Departure_Longitude__c: FieldValueFloat
122
+ Departure_Latitude__c: FieldValueFloat
123
+ Arrival_Airport__c: FieldValueString
124
+ Arrival_City__c: FieldValueString
125
+ Arrival_Longitude__c: FieldValueFloat
126
+ Arrival_Latitude__c: FieldValueFloat
127
+ Departure_DateTime__c: FieldValueString
128
+ Flight_Status__c: FieldValueString
129
+ Delay_Minutes__c: FieldValueFloat
130
+ Cabin_Class__c: FieldValueString
131
+ Contact__c: FieldValueString
132
+ }
133
+
134
+ type Flight__cEdge {
135
+ node: Flight__c!
136
+ cursor: String!
137
+ }
138
+
139
+ type Flight__cConnection {
140
+ edges: [Flight__cEdge!]!
141
+ pageInfo: PageInfo!
142
+ totalCount: Int
143
+ }
144
+
145
+ input Flight__cFilter {
146
+ Id: IDFilter
147
+ Flight_Number__c: StringFilter
148
+ Flight_Status__c: StringFilter
149
+ }
150
+
151
+ # Booking__c
152
+ type Booking__c {
153
+ Id: ID!
154
+ Contact__c: FieldValueString
155
+ Booking_Type__c: FieldValueString
156
+ Status__c: FieldValueString
157
+ Cost__c: FieldValueFloat
158
+ In_Policy__c: FieldValueBoolean
159
+ }
160
+
161
+ type Booking__cEdge {
162
+ node: Booking__c!
163
+ cursor: String!
164
+ }
165
+
166
+ type Booking__cConnection {
167
+ edges: [Booking__cEdge!]!
168
+ pageInfo: PageInfo!
169
+ totalCount: Int
170
+ }
171
+
172
+ input Booking__cFilter {
173
+ Id: IDFilter
174
+ Status__c: StringFilter
175
+ }
176
+
177
+ # Disruption__c
178
+ type Disruption__c {
179
+ Id: ID!
180
+ Flight_Number__c: FieldValueString
181
+ Disruption_Type__c: FieldValueString
182
+ Severity__c: FieldValueString
183
+ Status__c: FieldValueString
184
+ Impacted_Flight__c: FieldValueString
185
+ Trip__c: FieldValueString
186
+ City__c: FieldValueString
187
+ Affected_Traveler_Count__c: FieldValueFloat
188
+ Auto_Rebook_Eligible__c: FieldValueBoolean
189
+ Recommended_Action__c: FieldValueString
190
+ Description__c: FieldValueString
191
+ }
192
+
193
+ type Disruption__cEdge {
194
+ node: Disruption__c!
195
+ cursor: String!
196
+ }
197
+
198
+ type Disruption__cConnection {
199
+ edges: [Disruption__cEdge!]!
200
+ pageInfo: PageInfo!
201
+ totalCount: Int
202
+ }
203
+
204
+ input Disruption__cFilter {
205
+ Id: IDFilter
206
+ Severity__c: StringFilter
207
+ Status__c: StringFilter
208
+ }
209
+
210
+ # Rebooking_Action__c
211
+ type Rebooking_Action__c {
212
+ Id: ID!
213
+ Action_Type__c: FieldValueString
214
+ Status__c: FieldValueString
215
+ Handled_By__c: FieldValueString
216
+ Contact__c: FieldValueString
217
+ Original_Flight__c: FieldValueString
218
+ New_Flight__c: FieldValueString
219
+ Cost_Difference__c: FieldValueFloat
220
+ Notes__c: FieldValueString
221
+ Created_DateTime__c: FieldValueString
222
+ }
223
+
224
+ type Rebooking_Action__cEdge {
225
+ node: Rebooking_Action__c!
226
+ cursor: String!
227
+ }
228
+
229
+ type Rebooking_Action__cConnection {
230
+ edges: [Rebooking_Action__cEdge!]!
231
+ pageInfo: PageInfo!
232
+ totalCount: Int
233
+ }
234
+
235
+ input Rebooking_Action__cFilter {
236
+ Id: IDFilter
237
+ Status__c: StringFilter
238
+ }
239
+
240
+ # Travel_Policy__c
241
+ type Travel_Policy__c {
242
+ Id: ID!
243
+ Name: FieldValueString
244
+ Description__c: FieldValueString
245
+ Active__c: FieldValueBoolean
246
+ Policy_Tier__c: FieldValueString
247
+ Max_Flight_Cost__c: FieldValueFloat
248
+ Max_Hotel_Rate__c: FieldValueFloat
249
+ Advance_Booking_Days__c: FieldValueFloat
250
+ Preferred_Airlines__c: FieldValueString
251
+ Preferred_Hotel_Chains__c: FieldValueString
252
+ }
253
+
254
+ type Travel_Policy__cEdge {
255
+ node: Travel_Policy__c!
256
+ cursor: String!
257
+ }
258
+
259
+ type Travel_Policy__cConnection {
260
+ edges: [Travel_Policy__cEdge!]!
261
+ pageInfo: PageInfo!
262
+ totalCount: Int
263
+ }
264
+
265
+ input Travel_Policy__cFilter {
266
+ Id: IDFilter
267
+ Policy_Tier__c: StringFilter
268
+ }
269
+
270
+ # Pagination
271
+ type PageInfo {
272
+ hasNextPage: Boolean!
273
+ hasPreviousPage: Boolean!
274
+ startCursor: String
275
+ endCursor: String
276
+ }
277
+
278
+ # Filter input types
279
+ input IDFilter {
280
+ eq: ID
281
+ ne: ID
282
+ in: [ID!]
283
+ nin: [ID!]
284
+ }
285
+
286
+ input StringFilter {
287
+ eq: String
288
+ ne: String
289
+ like: String
290
+ in: [String!]
291
+ nin: [String!]
292
+ }
@@ -0,0 +1,49 @@
1
+ import { useState, useEffect } from "react";
2
+ import * as live from "@/data/engine-live-data";
3
+
4
+ const SIMULATED_LOAD_MS = 2000;
5
+
6
+ export interface EngineLiveData {
7
+ loading: boolean;
8
+ mapMarkers: typeof live.MAP_MARKERS;
9
+ mapArcs: typeof live.MAP_ARCS;
10
+ mapOverlays: typeof live.MAP_OVERLAYS;
11
+ flightStatusList: typeof live.FLIGHT_STATUS_LIST;
12
+ travelerCards: typeof live.TRAVELER_CARDS;
13
+ disruptionCards: typeof live.DISRUPTION_CARDS;
14
+ escalationCards: typeof live.ESCALATION_CARDS;
15
+ monthlySpend: typeof live.MONTHLY_SPEND;
16
+ metrics: typeof live.METRICS;
17
+ }
18
+
19
+ /**
20
+ * Provides the live dataset for the Engine Travel Command Center.
21
+ *
22
+ * Simulates a 2-second network fetch, then resolves with all live data.
23
+ * Does NOT control the data mode — that's handled by ENABLE_SAMPLE_DATA_CACHE
24
+ * in src/lib/dataStrategy.ts. When the flag is false, every useDataSource call
25
+ * returns its live prop (which this hook provides) instead of its sample prop.
26
+ */
27
+ export function useEngineLiveData(): EngineLiveData {
28
+ const [loading, setLoading] = useState(true);
29
+
30
+ useEffect(() => {
31
+ const timer = setTimeout(() => {
32
+ setLoading(false);
33
+ }, SIMULATED_LOAD_MS);
34
+ return () => clearTimeout(timer);
35
+ }, []);
36
+
37
+ return {
38
+ loading,
39
+ mapMarkers: live.MAP_MARKERS,
40
+ mapArcs: live.MAP_ARCS,
41
+ mapOverlays: live.MAP_OVERLAYS,
42
+ flightStatusList: live.FLIGHT_STATUS_LIST,
43
+ travelerCards: live.TRAVELER_CARDS,
44
+ disruptionCards: live.DISRUPTION_CARDS,
45
+ escalationCards: live.ESCALATION_CARDS,
46
+ monthlySpend: live.MONTHLY_SPEND,
47
+ metrics: live.METRICS,
48
+ };
49
+ }