@billsdk/time-travel 0.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,707 @@
1
+ "use client";
2
+
3
+ // src/client/overlay.tsx
4
+ import { useCallback, useEffect, useState } from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ function TimeTravelOverlay({
7
+ baseUrl = "/api/billing",
8
+ position = "bottom-right",
9
+ defaultCollapsed = true,
10
+ customerId
11
+ }) {
12
+ const [state, setState] = useState(null);
13
+ const [allCustomers, setAllCustomers] = useState([]);
14
+ const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
15
+ const [isLoading, setIsLoading] = useState(false);
16
+ const [isProcessingRenewals, setIsProcessingRenewals] = useState(false);
17
+ const [renewalResult, setRenewalResult] = useState(
18
+ null
19
+ );
20
+ const [dateInput, setDateInput] = useState("");
21
+ const [customerIdInput, setCustomerIdInput] = useState(customerId ?? "");
22
+ const [showAllCustomers, setShowAllCustomers] = useState(false);
23
+ const activeCustomerId = customerId ?? customerIdInput;
24
+ const fetchState = useCallback(async () => {
25
+ if (!activeCustomerId) {
26
+ setState(null);
27
+ return;
28
+ }
29
+ try {
30
+ const res = await fetch(`${baseUrl}/time-travel/get`, {
31
+ method: "POST",
32
+ headers: { "Content-Type": "application/json" },
33
+ body: JSON.stringify({ customerId: activeCustomerId })
34
+ });
35
+ if (res.ok) {
36
+ const data = await res.json();
37
+ setState(data);
38
+ if (data.simulatedTime) {
39
+ const datePart = data.simulatedTime.split("T")[0];
40
+ if (datePart) {
41
+ setDateInput(datePart);
42
+ }
43
+ }
44
+ }
45
+ } catch (error) {
46
+ console.error("[TimeTravelOverlay] Failed to fetch state:", error);
47
+ }
48
+ }, [baseUrl, activeCustomerId]);
49
+ const fetchAllCustomers = useCallback(async () => {
50
+ try {
51
+ const res = await fetch(`${baseUrl}/time-travel/list`);
52
+ if (res.ok) {
53
+ const data = await res.json();
54
+ setAllCustomers(data.customers);
55
+ }
56
+ } catch (error) {
57
+ console.error("[TimeTravelOverlay] Failed to fetch customers:", error);
58
+ }
59
+ }, [baseUrl]);
60
+ useEffect(() => {
61
+ fetchState();
62
+ fetchAllCustomers();
63
+ }, [fetchState, fetchAllCustomers]);
64
+ const advance = async (days, months = 0, hours = 0) => {
65
+ if (!activeCustomerId) return;
66
+ setIsLoading(true);
67
+ try {
68
+ const res = await fetch(`${baseUrl}/time-travel/advance`, {
69
+ method: "POST",
70
+ headers: { "Content-Type": "application/json" },
71
+ body: JSON.stringify({
72
+ customerId: activeCustomerId,
73
+ days,
74
+ months,
75
+ hours
76
+ })
77
+ });
78
+ if (res.ok) {
79
+ await fetchState();
80
+ await fetchAllCustomers();
81
+ }
82
+ } catch (error) {
83
+ console.error("[TimeTravelOverlay] Failed to advance:", error);
84
+ } finally {
85
+ setIsLoading(false);
86
+ }
87
+ };
88
+ const setTime = async (date) => {
89
+ if (!activeCustomerId) return;
90
+ setIsLoading(true);
91
+ try {
92
+ const res = await fetch(`${baseUrl}/time-travel/set`, {
93
+ method: "POST",
94
+ headers: { "Content-Type": "application/json" },
95
+ body: JSON.stringify({ customerId: activeCustomerId, date })
96
+ });
97
+ if (res.ok) {
98
+ await fetchState();
99
+ await fetchAllCustomers();
100
+ }
101
+ } catch (error) {
102
+ console.error("[TimeTravelOverlay] Failed to set time:", error);
103
+ } finally {
104
+ setIsLoading(false);
105
+ }
106
+ };
107
+ const reset = async () => {
108
+ if (!activeCustomerId) return;
109
+ setIsLoading(true);
110
+ try {
111
+ const res = await fetch(`${baseUrl}/time-travel/reset`, {
112
+ method: "POST",
113
+ headers: { "Content-Type": "application/json" },
114
+ body: JSON.stringify({ customerId: activeCustomerId })
115
+ });
116
+ if (res.ok) {
117
+ setDateInput("");
118
+ await fetchState();
119
+ await fetchAllCustomers();
120
+ }
121
+ } catch (error) {
122
+ console.error("[TimeTravelOverlay] Failed to reset:", error);
123
+ } finally {
124
+ setIsLoading(false);
125
+ }
126
+ };
127
+ const handleDateSubmit = () => {
128
+ if (dateInput) {
129
+ const date = new Date(dateInput);
130
+ date.setUTCHours(12, 0, 0, 0);
131
+ setTime(date.toISOString());
132
+ }
133
+ };
134
+ const processRenewals = async (dryRun = false) => {
135
+ if (!activeCustomerId) return;
136
+ setIsProcessingRenewals(true);
137
+ setRenewalResult(null);
138
+ try {
139
+ const params = new URLSearchParams({
140
+ customerId: activeCustomerId,
141
+ ...dryRun && { dryRun: "true" }
142
+ });
143
+ const res = await fetch(`${baseUrl}/renewals?${params.toString()}`);
144
+ if (res.ok) {
145
+ const data = await res.json();
146
+ setRenewalResult(data);
147
+ } else {
148
+ console.error("[TimeTravelOverlay] Renewals failed:", res.statusText);
149
+ }
150
+ } catch (error) {
151
+ console.error("[TimeTravelOverlay] Failed to process renewals:", error);
152
+ } finally {
153
+ setIsProcessingRenewals(false);
154
+ }
155
+ };
156
+ const positionStyles = {
157
+ "bottom-right": { bottom: 16, right: 16 },
158
+ "bottom-left": { bottom: 16, left: 16 },
159
+ "top-right": { top: 16, right: 16 },
160
+ "top-left": { top: 16, left: 16 }
161
+ };
162
+ const formatDate = (isoString) => {
163
+ const date = new Date(isoString);
164
+ return date.toLocaleDateString(void 0, {
165
+ weekday: "short",
166
+ year: "numeric",
167
+ month: "short",
168
+ day: "numeric"
169
+ });
170
+ };
171
+ const formatTime = (isoString) => {
172
+ const date = new Date(isoString);
173
+ return date.toLocaleTimeString(void 0, {
174
+ hour: "2-digit",
175
+ minute: "2-digit"
176
+ });
177
+ };
178
+ const truncateId = (id) => {
179
+ if (id.length <= 12) return id;
180
+ return `${id.slice(0, 6)}...${id.slice(-4)}`;
181
+ };
182
+ return /* @__PURE__ */ jsx(
183
+ "div",
184
+ {
185
+ style: {
186
+ position: "fixed",
187
+ ...positionStyles[position],
188
+ zIndex: 99999,
189
+ fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
190
+ fontSize: 14
191
+ },
192
+ children: isCollapsed ? /* @__PURE__ */ jsxs(
193
+ "button",
194
+ {
195
+ type: "button",
196
+ onClick: () => setIsCollapsed(false),
197
+ style: {
198
+ display: "flex",
199
+ alignItems: "center",
200
+ gap: 8,
201
+ padding: "8px 12px",
202
+ borderRadius: 8,
203
+ border: "none",
204
+ cursor: "pointer",
205
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
206
+ backgroundColor: state?.isSimulated ? "#fef3c7" : "#f3f4f6",
207
+ color: state?.isSimulated ? "#92400e" : "#374151",
208
+ fontWeight: 500,
209
+ transition: "all 0.2s"
210
+ },
211
+ children: [
212
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 16 }, children: state?.isSimulated ? "\u23F0" : "\u{1F550}" }),
213
+ /* @__PURE__ */ jsx("span", { children: state?.isSimulated && state.simulatedTime ? formatDate(state.simulatedTime) : "Real Time" }),
214
+ allCustomers.length > 0 && /* @__PURE__ */ jsx(
215
+ "span",
216
+ {
217
+ style: {
218
+ backgroundColor: "#3b82f6",
219
+ color: "white",
220
+ borderRadius: 9999,
221
+ padding: "2px 6px",
222
+ fontSize: 11,
223
+ fontWeight: 600
224
+ },
225
+ children: allCustomers.length
226
+ }
227
+ )
228
+ ]
229
+ }
230
+ ) : (
231
+ /* Expanded Panel */
232
+ /* @__PURE__ */ jsxs(
233
+ "div",
234
+ {
235
+ style: {
236
+ width: 320,
237
+ backgroundColor: "white",
238
+ borderRadius: 12,
239
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
240
+ border: "1px solid #e5e7eb",
241
+ overflow: "hidden"
242
+ },
243
+ children: [
244
+ /* @__PURE__ */ jsxs(
245
+ "div",
246
+ {
247
+ style: {
248
+ display: "flex",
249
+ justifyContent: "space-between",
250
+ alignItems: "center",
251
+ padding: "12px 16px",
252
+ backgroundColor: state?.isSimulated ? "#fef3c7" : "#f9fafb",
253
+ borderBottom: "1px solid #e5e7eb"
254
+ },
255
+ children: [
256
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
257
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 18 }, children: state?.isSimulated ? "\u23F0" : "\u{1F550}" }),
258
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: "#111827" }, children: "Time Travel" })
259
+ ] }),
260
+ /* @__PURE__ */ jsx(
261
+ "button",
262
+ {
263
+ type: "button",
264
+ onClick: () => setIsCollapsed(true),
265
+ style: {
266
+ padding: 4,
267
+ borderRadius: 4,
268
+ border: "none",
269
+ backgroundColor: "transparent",
270
+ cursor: "pointer",
271
+ color: "#6b7280",
272
+ fontSize: 18,
273
+ lineHeight: 1
274
+ },
275
+ children: "\xD7"
276
+ }
277
+ )
278
+ ]
279
+ }
280
+ ),
281
+ /* @__PURE__ */ jsxs("div", { style: { padding: 16 }, children: [
282
+ !customerId && /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
283
+ /* @__PURE__ */ jsx(
284
+ "div",
285
+ {
286
+ style: {
287
+ fontSize: 12,
288
+ color: "#6b7280",
289
+ marginBottom: 8,
290
+ textTransform: "uppercase",
291
+ letterSpacing: "0.05em"
292
+ },
293
+ children: "Customer ID"
294
+ }
295
+ ),
296
+ /* @__PURE__ */ jsx(
297
+ "input",
298
+ {
299
+ type: "text",
300
+ value: customerIdInput,
301
+ onChange: (e) => setCustomerIdInput(e.target.value),
302
+ onBlur: fetchState,
303
+ placeholder: "Enter customer ID\u2026",
304
+ style: {
305
+ width: "100%",
306
+ padding: "8px 12px",
307
+ borderRadius: 6,
308
+ border: "1px solid #e5e7eb",
309
+ fontSize: 14,
310
+ color: "#374151",
311
+ boxSizing: "border-box"
312
+ }
313
+ }
314
+ )
315
+ ] }),
316
+ customerId && /* @__PURE__ */ jsxs(
317
+ "div",
318
+ {
319
+ style: {
320
+ marginBottom: 16,
321
+ padding: "8px 12px",
322
+ backgroundColor: "#eff6ff",
323
+ borderRadius: 6,
324
+ fontSize: 12,
325
+ color: "#1e40af"
326
+ },
327
+ children: [
328
+ "Customer: ",
329
+ /* @__PURE__ */ jsx("strong", { children: truncateId(customerId) })
330
+ ]
331
+ }
332
+ ),
333
+ activeCustomerId ? /* @__PURE__ */ jsxs(Fragment, { children: [
334
+ /* @__PURE__ */ jsxs(
335
+ "div",
336
+ {
337
+ style: {
338
+ marginBottom: 16,
339
+ padding: 12,
340
+ backgroundColor: "#f9fafb",
341
+ borderRadius: 8
342
+ },
343
+ children: [
344
+ /* @__PURE__ */ jsx(
345
+ "div",
346
+ {
347
+ style: {
348
+ fontSize: 12,
349
+ color: "#6b7280",
350
+ marginBottom: 4,
351
+ textTransform: "uppercase",
352
+ letterSpacing: "0.05em"
353
+ },
354
+ children: state?.isSimulated ? "Simulated Time" : "Current Time"
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsx(
358
+ "div",
359
+ {
360
+ style: { fontSize: 16, fontWeight: 600, color: "#111827" },
361
+ children: state?.simulatedTime ? formatDate(state.simulatedTime) : state?.realTime ? formatDate(state.realTime) : "Loading..."
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: "#6b7280" }, children: state?.simulatedTime ? formatTime(state.simulatedTime) : state?.realTime ? formatTime(state.realTime) : "" })
365
+ ]
366
+ }
367
+ ),
368
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
369
+ /* @__PURE__ */ jsx(
370
+ "div",
371
+ {
372
+ style: {
373
+ fontSize: 12,
374
+ color: "#6b7280",
375
+ marginBottom: 8,
376
+ textTransform: "uppercase",
377
+ letterSpacing: "0.05em"
378
+ },
379
+ children: "Quick Advance"
380
+ }
381
+ ),
382
+ /* @__PURE__ */ jsx(
383
+ "div",
384
+ {
385
+ style: {
386
+ display: "grid",
387
+ gridTemplateColumns: "repeat(3, 1fr)",
388
+ gap: 8
389
+ },
390
+ children: [
391
+ { label: "+1 day", days: 1 },
392
+ { label: "+1 week", days: 7 },
393
+ { label: "+1 month", months: 1 }
394
+ ].map((action) => /* @__PURE__ */ jsx(
395
+ "button",
396
+ {
397
+ type: "button",
398
+ onClick: () => advance(action.days ?? 0, action.months ?? 0),
399
+ disabled: isLoading,
400
+ style: {
401
+ padding: "8px 12px",
402
+ borderRadius: 6,
403
+ border: "1px solid #e5e7eb",
404
+ backgroundColor: "white",
405
+ cursor: isLoading ? "not-allowed" : "pointer",
406
+ color: "#374151",
407
+ fontSize: 13,
408
+ fontWeight: 500,
409
+ transition: "all 0.15s",
410
+ opacity: isLoading ? 0.5 : 1
411
+ },
412
+ children: action.label
413
+ },
414
+ action.label
415
+ ))
416
+ }
417
+ )
418
+ ] }),
419
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
420
+ /* @__PURE__ */ jsx(
421
+ "div",
422
+ {
423
+ style: {
424
+ fontSize: 12,
425
+ color: "#6b7280",
426
+ marginBottom: 8,
427
+ textTransform: "uppercase",
428
+ letterSpacing: "0.05em"
429
+ },
430
+ children: "Go to Date"
431
+ }
432
+ ),
433
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8 }, children: [
434
+ /* @__PURE__ */ jsx(
435
+ "input",
436
+ {
437
+ type: "date",
438
+ value: dateInput,
439
+ onChange: (e) => {
440
+ const target = e.target;
441
+ setDateInput(target.value);
442
+ },
443
+ style: {
444
+ flex: 1,
445
+ padding: "8px 12px",
446
+ borderRadius: 6,
447
+ border: "1px solid #e5e7eb",
448
+ fontSize: 14,
449
+ color: "#374151"
450
+ }
451
+ }
452
+ ),
453
+ /* @__PURE__ */ jsx(
454
+ "button",
455
+ {
456
+ type: "button",
457
+ onClick: handleDateSubmit,
458
+ disabled: isLoading || !dateInput,
459
+ style: {
460
+ padding: "8px 16px",
461
+ borderRadius: 6,
462
+ border: "none",
463
+ backgroundColor: "#3b82f6",
464
+ color: "white",
465
+ cursor: isLoading || !dateInput ? "not-allowed" : "pointer",
466
+ fontSize: 14,
467
+ fontWeight: 500,
468
+ opacity: isLoading || !dateInput ? 0.5 : 1
469
+ },
470
+ children: "Go"
471
+ }
472
+ )
473
+ ] })
474
+ ] }),
475
+ state?.isSimulated && /* @__PURE__ */ jsx(
476
+ "button",
477
+ {
478
+ type: "button",
479
+ onClick: reset,
480
+ disabled: isLoading,
481
+ style: {
482
+ width: "100%",
483
+ padding: "10px 16px",
484
+ borderRadius: 6,
485
+ border: "1px solid #ef4444",
486
+ backgroundColor: "white",
487
+ color: "#ef4444",
488
+ cursor: isLoading ? "not-allowed" : "pointer",
489
+ fontSize: 14,
490
+ fontWeight: 500,
491
+ opacity: isLoading ? 0.5 : 1,
492
+ marginBottom: 16
493
+ },
494
+ children: "Reset to Real Time"
495
+ }
496
+ ),
497
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
498
+ /* @__PURE__ */ jsx(
499
+ "div",
500
+ {
501
+ style: {
502
+ fontSize: 12,
503
+ color: "#6b7280",
504
+ marginBottom: 8,
505
+ textTransform: "uppercase",
506
+ letterSpacing: "0.05em"
507
+ },
508
+ children: "Billing Actions"
509
+ }
510
+ ),
511
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8 }, children: [
512
+ /* @__PURE__ */ jsx(
513
+ "button",
514
+ {
515
+ type: "button",
516
+ onClick: () => processRenewals(true),
517
+ disabled: isProcessingRenewals,
518
+ title: "Check what would happen without actually charging",
519
+ style: {
520
+ flex: 1,
521
+ padding: "8px 12px",
522
+ borderRadius: 6,
523
+ border: "1px solid #e5e7eb",
524
+ backgroundColor: "white",
525
+ cursor: isProcessingRenewals ? "not-allowed" : "pointer",
526
+ color: "#374151",
527
+ fontSize: 13,
528
+ fontWeight: 500,
529
+ opacity: isProcessingRenewals ? 0.5 : 1
530
+ },
531
+ children: isProcessingRenewals ? "..." : "Dry Run"
532
+ }
533
+ ),
534
+ /* @__PURE__ */ jsx(
535
+ "button",
536
+ {
537
+ type: "button",
538
+ onClick: () => processRenewals(false),
539
+ disabled: isProcessingRenewals,
540
+ title: "Process renewals and charge customers",
541
+ style: {
542
+ flex: 1,
543
+ padding: "8px 12px",
544
+ borderRadius: 6,
545
+ border: "none",
546
+ backgroundColor: "#10b981",
547
+ cursor: isProcessingRenewals ? "not-allowed" : "pointer",
548
+ color: "white",
549
+ fontSize: 13,
550
+ fontWeight: 500,
551
+ opacity: isProcessingRenewals ? 0.5 : 1
552
+ },
553
+ children: isProcessingRenewals ? "Processing..." : "Process Renewals"
554
+ }
555
+ )
556
+ ] }),
557
+ renewalResult && /* @__PURE__ */ jsx(
558
+ "div",
559
+ {
560
+ style: {
561
+ marginTop: 8,
562
+ padding: 12,
563
+ backgroundColor: renewalResult.failed > 0 ? "#fef2f2" : "#f0fdf4",
564
+ borderRadius: 6,
565
+ fontSize: 12
566
+ },
567
+ children: /* @__PURE__ */ jsxs(
568
+ "div",
569
+ {
570
+ style: {
571
+ display: "grid",
572
+ gridTemplateColumns: "repeat(2, 1fr)",
573
+ gap: 4
574
+ },
575
+ children: [
576
+ /* @__PURE__ */ jsxs("div", { children: [
577
+ /* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: "Processed:" }),
578
+ " ",
579
+ /* @__PURE__ */ jsx("strong", { children: renewalResult.processed })
580
+ ] }),
581
+ /* @__PURE__ */ jsxs("div", { children: [
582
+ /* @__PURE__ */ jsx("span", { style: { color: "#059669" }, children: "Succeeded:" }),
583
+ " ",
584
+ /* @__PURE__ */ jsx("strong", { style: { color: "#059669" }, children: renewalResult.succeeded })
585
+ ] }),
586
+ /* @__PURE__ */ jsxs("div", { children: [
587
+ /* @__PURE__ */ jsx("span", { style: { color: "#dc2626" }, children: "Failed:" }),
588
+ " ",
589
+ /* @__PURE__ */ jsx("strong", { style: { color: "#dc2626" }, children: renewalResult.failed })
590
+ ] }),
591
+ /* @__PURE__ */ jsxs("div", { children: [
592
+ /* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: "Skipped:" }),
593
+ " ",
594
+ /* @__PURE__ */ jsx("strong", { children: renewalResult.skipped })
595
+ ] })
596
+ ]
597
+ }
598
+ )
599
+ }
600
+ )
601
+ ] })
602
+ ] }) : /* @__PURE__ */ jsx(
603
+ "div",
604
+ {
605
+ style: {
606
+ padding: 16,
607
+ textAlign: "center",
608
+ color: "#6b7280"
609
+ },
610
+ children: "Enter a customer ID to control time"
611
+ }
612
+ ),
613
+ allCustomers.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
614
+ /* @__PURE__ */ jsxs(
615
+ "button",
616
+ {
617
+ type: "button",
618
+ onClick: () => setShowAllCustomers(!showAllCustomers),
619
+ style: {
620
+ width: "100%",
621
+ padding: "8px 12px",
622
+ borderRadius: 6,
623
+ border: "1px solid #e5e7eb",
624
+ backgroundColor: "#f9fafb",
625
+ cursor: "pointer",
626
+ color: "#374151",
627
+ fontSize: 13,
628
+ fontWeight: 500,
629
+ display: "flex",
630
+ justifyContent: "space-between",
631
+ alignItems: "center"
632
+ },
633
+ children: [
634
+ /* @__PURE__ */ jsxs("span", { children: [
635
+ allCustomers.length,
636
+ " customer(s) with simulated time"
637
+ ] }),
638
+ /* @__PURE__ */ jsx("span", { children: showAllCustomers ? "\u25B2" : "\u25BC" })
639
+ ]
640
+ }
641
+ ),
642
+ showAllCustomers && /* @__PURE__ */ jsx(
643
+ "div",
644
+ {
645
+ style: {
646
+ marginTop: 8,
647
+ maxHeight: 150,
648
+ overflowY: "auto",
649
+ border: "1px solid #e5e7eb",
650
+ borderRadius: 6
651
+ },
652
+ children: allCustomers.map((c) => /* @__PURE__ */ jsxs(
653
+ "div",
654
+ {
655
+ style: {
656
+ padding: "8px 12px",
657
+ borderBottom: "1px solid #f3f4f6",
658
+ fontSize: 12,
659
+ display: "flex",
660
+ justifyContent: "space-between",
661
+ backgroundColor: c.customerId === activeCustomerId ? "#eff6ff" : "transparent"
662
+ },
663
+ children: [
664
+ /* @__PURE__ */ jsx(
665
+ "span",
666
+ {
667
+ style: {
668
+ fontFamily: "monospace",
669
+ color: "#374151"
670
+ },
671
+ children: truncateId(c.customerId)
672
+ }
673
+ ),
674
+ /* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: c.simulatedTime ? formatDate(c.simulatedTime) : "\u2014" })
675
+ ]
676
+ },
677
+ c.customerId
678
+ ))
679
+ }
680
+ )
681
+ ] })
682
+ ] }),
683
+ /* @__PURE__ */ jsx(
684
+ "div",
685
+ {
686
+ style: {
687
+ padding: "8px 16px",
688
+ backgroundColor: "#fef2f2",
689
+ borderTop: "1px solid #fecaca",
690
+ fontSize: 11,
691
+ color: "#991b1b",
692
+ textAlign: "center"
693
+ },
694
+ children: "Development only - Do not use in production"
695
+ }
696
+ )
697
+ ]
698
+ }
699
+ )
700
+ )
701
+ }
702
+ );
703
+ }
704
+ export {
705
+ TimeTravelOverlay
706
+ };
707
+ //# sourceMappingURL=index.js.map