@dataemergencia/emergency 0.3.0 → 0.5.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.
- package/README.md +1 -1
- package/dist/iife/emergency.iife.global.js +24 -24
- package/dist/index.cjs +1000 -312
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1001 -313
- package/dist/styles.css +680 -52
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -391,6 +391,7 @@ function createBffClient(options) {
|
|
|
391
391
|
const copy = {
|
|
392
392
|
panelLabel: "Panel de emergencia",
|
|
393
393
|
close: "Cerrar panel de emergencia",
|
|
394
|
+
back: "Volver",
|
|
394
395
|
question: "¿Tiene usted una emergencia?",
|
|
395
396
|
illustrationAlt: "Ícono paramédico",
|
|
396
397
|
emergency: "Emergencia",
|
|
@@ -762,6 +763,7 @@ function createEmergencyStore(config) {
|
|
|
762
763
|
lastError: null,
|
|
763
764
|
geolocation: null,
|
|
764
765
|
geolocationError: null,
|
|
766
|
+
contactPhone: null,
|
|
765
767
|
realtimeStatus: "idle",
|
|
766
768
|
abortResult: null,
|
|
767
769
|
simulationResult: null,
|
|
@@ -1204,7 +1206,8 @@ function createEmergencyController(deps) {
|
|
|
1204
1206
|
patch({
|
|
1205
1207
|
panelOpen: false,
|
|
1206
1208
|
abortConfirmation: false,
|
|
1207
|
-
simulationConfirmation: false
|
|
1209
|
+
simulationConfirmation: false,
|
|
1210
|
+
contactPhone: null
|
|
1208
1211
|
});
|
|
1209
1212
|
events.emit("panel:closed", { reason });
|
|
1210
1213
|
}
|
|
@@ -1253,6 +1256,7 @@ function createEmergencyController(deps) {
|
|
|
1253
1256
|
lastError: null,
|
|
1254
1257
|
geolocation: null,
|
|
1255
1258
|
geolocationError: null,
|
|
1259
|
+
contactPhone: null,
|
|
1256
1260
|
realtimeStatus: "idle",
|
|
1257
1261
|
abortResult: null,
|
|
1258
1262
|
simulationResult: null,
|
|
@@ -1294,7 +1298,8 @@ function createEmergencyController(deps) {
|
|
|
1294
1298
|
geolocationError: null,
|
|
1295
1299
|
...state.geolocationError !== null || state.abortResult?.ok === false || state.simulationResult?.ok === false || state.phase.kind === "ready" && state.lastError !== null ? { lastError: null } : {}
|
|
1296
1300
|
});
|
|
1297
|
-
}
|
|
1301
|
+
},
|
|
1302
|
+
setContactPhone: (phone) => patch({ contactPhone: phone })
|
|
1298
1303
|
},
|
|
1299
1304
|
store,
|
|
1300
1305
|
events
|
|
@@ -1469,74 +1474,6 @@ function validateConfig(config) {
|
|
|
1469
1474
|
};
|
|
1470
1475
|
}
|
|
1471
1476
|
|
|
1472
|
-
// src/react/components/icons/paramedical-mark.tsx
|
|
1473
|
-
/**
|
|
1474
|
-
* Neutral inline illustration used by the idle panel.
|
|
1475
|
-
*/
|
|
1476
|
-
function ParamedicalMark({ className, title }) {
|
|
1477
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1478
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1479
|
-
version: "1.0",
|
|
1480
|
-
viewBox: "0 0 192 192",
|
|
1481
|
-
width: "192",
|
|
1482
|
-
height: "192",
|
|
1483
|
-
id: "Star of life",
|
|
1484
|
-
className,
|
|
1485
|
-
"aria-label": title,
|
|
1486
|
-
children: [
|
|
1487
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { id: "defs2886" }),
|
|
1488
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
1489
|
-
id: "cross",
|
|
1490
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1491
|
-
d: "m 74,133 0,52 44,0 0,-52 44,26 22,-38 L 140,96 184,70 162,32 117,58 117,7 74,7 74,58 30,32 8,70 52,96 8,121 30,159 z",
|
|
1492
|
-
id: "outline",
|
|
1493
|
-
style: {
|
|
1494
|
-
fill: "none",
|
|
1495
|
-
stroke: "#3333bb",
|
|
1496
|
-
strokeWidth: 6
|
|
1497
|
-
}
|
|
1498
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1499
|
-
d: "m 74,133 0,52 44,0 0,-52 44,26 22,-38 L 140,96 184,70 162,32 117,58 117,7 74,7 74,58 30,32 8,70 52,96 8,121 30,159 z",
|
|
1500
|
-
id: "inner",
|
|
1501
|
-
style: {
|
|
1502
|
-
fill: "#0000bb",
|
|
1503
|
-
fillRule: "evenodd",
|
|
1504
|
-
stroke: "#ffffff",
|
|
1505
|
-
strokeWidth: 2
|
|
1506
|
-
}
|
|
1507
|
-
})]
|
|
1508
|
-
}),
|
|
1509
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
1510
|
-
id: "symbols",
|
|
1511
|
-
style: {
|
|
1512
|
-
fill: "#ffffff",
|
|
1513
|
-
fillRule: "evenodd",
|
|
1514
|
-
stroke: "#3333bb",
|
|
1515
|
-
strokeWidth: 2
|
|
1516
|
-
},
|
|
1517
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1518
|
-
d: "m 93,166 c 0,7 6,7 6,0 l 3,-138 c 0,-8 -12,-8 -12,0 l 3,135 0,3 z",
|
|
1519
|
-
id: "rod"
|
|
1520
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
1521
|
-
id: "snake",
|
|
1522
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1523
|
-
d: "m 100,153 c 7,4 3,15 -3,15 2,-5 3,-9 3,-15 z m 1,-40 c 10,9 4,22 -3,26 -6,3 -6,7 -6,15 -9,-10 -4,-19 4,-24 5,-4 5,-10 5,-17 z m 1,-30 c 0,11 -17,14 -17,22 0,3 1,9 6,12 0,-11 9,-12 15,-18 7,-7 7,-19 -4,-28 0,4 0,8 0,12 z M 90,77 C 80,69 76,55 80,46 c 3,-10 20,-11 20,-3 0,8 -20,3 -13,16 l 3,5 0,13 z",
|
|
1524
|
-
id: "body"
|
|
1525
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1526
|
-
d: "m 95,43 c 7,-3 -7,-3 0,0 z",
|
|
1527
|
-
id: "eye",
|
|
1528
|
-
style: {
|
|
1529
|
-
fill: "#3333bb",
|
|
1530
|
-
fillRule: "evenodd",
|
|
1531
|
-
stroke: "none"
|
|
1532
|
-
}
|
|
1533
|
-
})]
|
|
1534
|
-
})]
|
|
1535
|
-
})
|
|
1536
|
-
]
|
|
1537
|
-
});
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
1477
|
// src/react/components/Icon/index.tsx
|
|
1541
1478
|
/** Icons whose artwork does not fit the default 24x24 grid need their own canvas. */
|
|
1542
1479
|
const viewBoxes = { emergency: "0 0 640 640" };
|
|
@@ -1593,6 +1530,23 @@ const paths = {
|
|
|
1593
1530
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 7h.01" })
|
|
1594
1531
|
] }),
|
|
1595
1532
|
"arrow-left": /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M19 12H5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m12 19-7-7 7-7" })] }),
|
|
1533
|
+
"map-pin": /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 22s7-6.2 7-12a7 7 0 1 0-14 0c0 5.8 7 12 7 12z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1534
|
+
cx: "12",
|
|
1535
|
+
cy: "10",
|
|
1536
|
+
r: "2.5"
|
|
1537
|
+
})] }),
|
|
1538
|
+
"credit-card-plus": /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1539
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 18H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5" }),
|
|
1540
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M18 12h.01" }),
|
|
1541
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M19 22v-6" }),
|
|
1542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m22 19-3-3-3 3" }),
|
|
1543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M6 12h.01" }),
|
|
1544
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1545
|
+
cx: "12",
|
|
1546
|
+
cy: "12",
|
|
1547
|
+
r: "2"
|
|
1548
|
+
})
|
|
1549
|
+
] }),
|
|
1596
1550
|
emergency: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M272.5 96C272.5 78.3 286.8 64 304.5 64L336.5 64C354.2 64 368.5 78.3 368.5 96L368.5 236.9L490.5 166.5C505.8 157.7 525.4 162.9 534.2 178.2L550.2 205.9C559 221.2 553.8 240.8 538.5 249.6L416.5 320L538.5 390.4C553.8 399.2 559.1 418.8 550.2 434.1L534.2 461.8C525.4 477.1 505.8 482.4 490.5 473.5L368.5 403.1L368.5 544C368.5 561.7 354.2 576 336.5 576L304.5 576C286.8 576 272.5 561.7 272.5 544L272.5 403.1L150.5 473.5C135.2 482.3 115.6 477.1 106.8 461.8L90.8 434.1C82 418.8 87.2 399.2 102.5 390.4L224.5 320L102.5 249.6C87.2 240.8 82 221.2 90.8 205.9L106.8 178.2C115.6 162.9 135.2 157.7 150.5 166.5L272.5 236.9L272.5 96z" }) })
|
|
1597
1551
|
};
|
|
1598
1552
|
function Icon({ name, className, title }) {
|
|
@@ -1622,6 +1576,16 @@ var panel_module_default = {
|
|
|
1622
1576
|
"de-emergency-slide-in": "de-emergency-de-emergency-slide-in-nA5Hwa",
|
|
1623
1577
|
"de-emergency-slide-up": "de-emergency-de-emergency-slide-up-nA5Hwa",
|
|
1624
1578
|
"de-emergency-spin": "de-emergency-de-emergency-spin-nA5Hwa",
|
|
1579
|
+
"emergency-availability": "de-emergency-emergency-availability-nA5Hwa",
|
|
1580
|
+
"emergency-availability__card": "de-emergency-emergency-availability__card-nA5Hwa",
|
|
1581
|
+
"emergency-availability__card-body": "de-emergency-emergency-availability__card-body-nA5Hwa",
|
|
1582
|
+
"emergency-availability__card-header": "de-emergency-emergency-availability__card-header-nA5Hwa",
|
|
1583
|
+
"emergency-availability__card-title": "de-emergency-emergency-availability__card-title-nA5Hwa",
|
|
1584
|
+
"emergency-availability__details": "de-emergency-emergency-availability__details-nA5Hwa",
|
|
1585
|
+
"emergency-availability__label": "de-emergency-emergency-availability__label-nA5Hwa",
|
|
1586
|
+
"emergency-availability__recharge": "de-emergency-emergency-availability__recharge-nA5Hwa",
|
|
1587
|
+
"emergency-availability__rounds": "de-emergency-emergency-availability__rounds-nA5Hwa",
|
|
1588
|
+
"emergency-availability__rounds-group": "de-emergency-emergency-availability__rounds-group-nA5Hwa",
|
|
1625
1589
|
"emergency-confirmation": "de-emergency-emergency-confirmation-nA5Hwa",
|
|
1626
1590
|
"emergency-confirmation__body": "de-emergency-emergency-confirmation__body-nA5Hwa",
|
|
1627
1591
|
"emergency-confirmation__button": "de-emergency-emergency-confirmation__button-nA5Hwa",
|
|
@@ -1646,7 +1610,12 @@ var panel_module_default = {
|
|
|
1646
1610
|
"emergency-feedback": "de-emergency-emergency-feedback-nA5Hwa",
|
|
1647
1611
|
"emergency-feedback__dismiss": "de-emergency-emergency-feedback__dismiss-nA5Hwa",
|
|
1648
1612
|
"emergency-panel": "de-emergency-emergency-panel-nA5Hwa",
|
|
1613
|
+
"emergency-panel__availability-region": "de-emergency-emergency-panel__availability-region-nA5Hwa",
|
|
1649
1614
|
"emergency-panel__body": "de-emergency-emergency-panel__body-nA5Hwa",
|
|
1615
|
+
"emergency-panel__body--pre-emergency": "de-emergency-emergency-panel__body--pre-emergency-nA5Hwa",
|
|
1616
|
+
"emergency-panel__body--pricing": "de-emergency-emergency-panel__body--pricing-nA5Hwa",
|
|
1617
|
+
"emergency-panel__body-split": "de-emergency-emergency-panel__body-split-nA5Hwa",
|
|
1618
|
+
"emergency-panel__body-split--with-availability": "de-emergency-emergency-panel__body-split--with-availability-nA5Hwa",
|
|
1650
1619
|
"emergency-panel__body-title": "de-emergency-emergency-panel__body-title-nA5Hwa",
|
|
1651
1620
|
"emergency-panel__body-title-container": "de-emergency-emergency-panel__body-title-container-nA5Hwa",
|
|
1652
1621
|
"emergency-panel__button": "de-emergency-emergency-panel__button-nA5Hwa",
|
|
@@ -1654,16 +1623,60 @@ var panel_module_default = {
|
|
|
1654
1623
|
"emergency-panel__button--simulation": "de-emergency-emergency-panel__button--simulation-nA5Hwa",
|
|
1655
1624
|
"emergency-panel__close-button": "de-emergency-emergency-panel__close-button-nA5Hwa",
|
|
1656
1625
|
"emergency-panel__close-icon": "de-emergency-emergency-panel__close-icon-nA5Hwa",
|
|
1626
|
+
"emergency-panel__divider": "de-emergency-emergency-panel__divider-nA5Hwa",
|
|
1657
1627
|
"emergency-panel__footer": "de-emergency-emergency-panel__footer-nA5Hwa",
|
|
1628
|
+
"emergency-panel__footer--single": "de-emergency-emergency-panel__footer--single-nA5Hwa",
|
|
1658
1629
|
"emergency-panel__header": "de-emergency-emergency-panel__header-nA5Hwa",
|
|
1630
|
+
"emergency-panel__header--close-only": "de-emergency-emergency-panel__header--close-only-nA5Hwa",
|
|
1631
|
+
"emergency-panel__prompt-region": "de-emergency-emergency-panel__prompt-region-nA5Hwa",
|
|
1632
|
+
"emergency-panel__sr-only": "de-emergency-emergency-panel__sr-only-nA5Hwa",
|
|
1659
1633
|
"emergency-panel__title": "de-emergency-emergency-panel__title-nA5Hwa",
|
|
1660
1634
|
"emergency-panel--hidden": "de-emergency-emergency-panel--hidden-nA5Hwa",
|
|
1635
|
+
"emergency-pre-emergency": "de-emergency-emergency-pre-emergency-nA5Hwa",
|
|
1636
|
+
"emergency-pre-emergency__error": "de-emergency-emergency-pre-emergency__error-nA5Hwa",
|
|
1637
|
+
"emergency-pre-emergency__form": "de-emergency-emergency-pre-emergency__form-nA5Hwa",
|
|
1638
|
+
"emergency-pre-emergency__input": "de-emergency-emergency-pre-emergency__input-nA5Hwa",
|
|
1639
|
+
"emergency-pre-emergency__input--area-code": "de-emergency-emergency-pre-emergency__input--area-code-nA5Hwa",
|
|
1640
|
+
"emergency-pre-emergency__input--invalid": "de-emergency-emergency-pre-emergency__input--invalid-nA5Hwa",
|
|
1641
|
+
"emergency-pre-emergency__input--number": "de-emergency-emergency-pre-emergency__input--number-nA5Hwa",
|
|
1642
|
+
"emergency-pre-emergency__input--valid": "de-emergency-emergency-pre-emergency__input--valid-nA5Hwa",
|
|
1643
|
+
"emergency-pre-emergency__label": "de-emergency-emergency-pre-emergency__label-nA5Hwa",
|
|
1644
|
+
"emergency-pre-emergency__notice": "de-emergency-emergency-pre-emergency__notice-nA5Hwa",
|
|
1645
|
+
"emergency-pre-emergency__notice-icon": "de-emergency-emergency-pre-emergency__notice-icon-nA5Hwa",
|
|
1646
|
+
"emergency-pre-emergency__notice-text": "de-emergency-emergency-pre-emergency__notice-text-nA5Hwa",
|
|
1647
|
+
"emergency-pre-emergency__phone-row": "de-emergency-emergency-pre-emergency__phone-row-nA5Hwa",
|
|
1648
|
+
"emergency-pricing": "de-emergency-emergency-pricing-nA5Hwa",
|
|
1649
|
+
"emergency-pricing__badge": "de-emergency-emergency-pricing__badge-nA5Hwa",
|
|
1650
|
+
"emergency-pricing__heading": "de-emergency-emergency-pricing__heading-nA5Hwa",
|
|
1651
|
+
"emergency-pricing__package": "de-emergency-emergency-pricing__package-nA5Hwa",
|
|
1652
|
+
"emergency-pricing__package--highlighted": "de-emergency-emergency-pricing__package--highlighted-nA5Hwa",
|
|
1653
|
+
"emergency-pricing__package-caption": "de-emergency-emergency-pricing__package-caption-nA5Hwa",
|
|
1654
|
+
"emergency-pricing__package-footnote": "de-emergency-emergency-pricing__package-footnote-nA5Hwa",
|
|
1655
|
+
"emergency-pricing__package-header": "de-emergency-emergency-pricing__package-header-nA5Hwa",
|
|
1656
|
+
"emergency-pricing__package-label": "de-emergency-emergency-pricing__package-label-nA5Hwa",
|
|
1657
|
+
"emergency-pricing__package-name": "de-emergency-emergency-pricing__package-name-nA5Hwa",
|
|
1658
|
+
"emergency-pricing__price": "de-emergency-emergency-pricing__price-nA5Hwa",
|
|
1659
|
+
"emergency-pricing__price-meta": "de-emergency-emergency-pricing__price-meta-nA5Hwa",
|
|
1660
|
+
"emergency-pricing__price-note": "de-emergency-emergency-pricing__price-note-nA5Hwa",
|
|
1661
|
+
"emergency-pricing__price-row": "de-emergency-emergency-pricing__price-row-nA5Hwa",
|
|
1662
|
+
"emergency-pricing__select": "de-emergency-emergency-pricing__select-nA5Hwa",
|
|
1663
|
+
"emergency-pricing__stat": "de-emergency-emergency-pricing__stat-nA5Hwa",
|
|
1664
|
+
"emergency-pricing__stat-divider": "de-emergency-emergency-pricing__stat-divider-nA5Hwa",
|
|
1665
|
+
"emergency-pricing__stat-label": "de-emergency-emergency-pricing__stat-label-nA5Hwa",
|
|
1666
|
+
"emergency-pricing__stat-value": "de-emergency-emergency-pricing__stat-value-nA5Hwa",
|
|
1667
|
+
"emergency-pricing__stats": "de-emergency-emergency-pricing__stats-nA5Hwa",
|
|
1668
|
+
"emergency-pricing__subtitle": "de-emergency-emergency-pricing__subtitle-nA5Hwa",
|
|
1669
|
+
"emergency-pricing__title": "de-emergency-emergency-pricing__title-nA5Hwa",
|
|
1670
|
+
"emergency-pricing__titles": "de-emergency-emergency-pricing__titles-nA5Hwa",
|
|
1661
1671
|
"emergency-resume-notification-button": "de-emergency-emergency-resume-notification-button-nA5Hwa",
|
|
1662
1672
|
"emergency-resume-notification-card": "de-emergency-emergency-resume-notification-card-nA5Hwa",
|
|
1663
1673
|
"emergency-resume-notification-icon": "de-emergency-emergency-resume-notification-icon-nA5Hwa",
|
|
1664
1674
|
"emergency-resume-notification-message": "de-emergency-emergency-resume-notification-message-nA5Hwa",
|
|
1665
1675
|
"emergency-resume-notification-overlay": "de-emergency-emergency-resume-notification-overlay-nA5Hwa",
|
|
1666
1676
|
"emergency-resume-notification-title": "de-emergency-emergency-resume-notification-title-nA5Hwa",
|
|
1677
|
+
"emergency-screen": "de-emergency-emergency-screen-nA5Hwa",
|
|
1678
|
+
"emergency-screen__placeholder": "de-emergency-emergency-screen__placeholder-nA5Hwa",
|
|
1679
|
+
"emergency-screen__placeholder-text": "de-emergency-emergency-screen__placeholder-text-nA5Hwa",
|
|
1667
1680
|
"emergency-status__abort-btn": "de-emergency-emergency-status__abort-btn-nA5Hwa",
|
|
1668
1681
|
"emergency-status__body": "de-emergency-emergency-status__body-nA5Hwa",
|
|
1669
1682
|
"emergency-status__cell": "de-emergency-emergency-status__cell-nA5Hwa",
|
|
@@ -1709,6 +1722,532 @@ function cls(...names) {
|
|
|
1709
1722
|
return names.filter((name) => Boolean(name)).map((name) => panel_module_default[name] ?? "").filter(Boolean).join(" ");
|
|
1710
1723
|
}
|
|
1711
1724
|
|
|
1725
|
+
// src/react/components/EmergencyConfirmation/index.tsx
|
|
1726
|
+
function EmergencyConfirmation(props) {
|
|
1727
|
+
const { abortConfirmation, simulationConfirmation, onCancelAbort, onCancelSimulation, onConfirmAbort, onConfirmSimulation } = props;
|
|
1728
|
+
const cardRef = (0, react.useRef)(null);
|
|
1729
|
+
const titleId = (0, react.useId)();
|
|
1730
|
+
const danger = abortConfirmation;
|
|
1731
|
+
const open = abortConfirmation || simulationConfirmation;
|
|
1732
|
+
(0, react.useEffect)(() => {
|
|
1733
|
+
if (open) cardRef.current?.querySelector("button")?.focus();
|
|
1734
|
+
}, [open]);
|
|
1735
|
+
if (!open) return null;
|
|
1736
|
+
const title = danger ? copy.abortConfirmTitle : copy.simulateConfirmTitle;
|
|
1737
|
+
const text = danger ? copy.abortConfirmText : copy.simulateConfirmText;
|
|
1738
|
+
const tone = danger ? "danger" : "information";
|
|
1739
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1740
|
+
className: cls("emergency-confirmation"),
|
|
1741
|
+
role: "dialog",
|
|
1742
|
+
"aria-modal": "true",
|
|
1743
|
+
"aria-labelledby": titleId,
|
|
1744
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1745
|
+
ref: cardRef,
|
|
1746
|
+
className: cls("emergency-confirmation__card"),
|
|
1747
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1748
|
+
className: cls("emergency-confirmation__body"),
|
|
1749
|
+
children: [
|
|
1750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1751
|
+
className: cls("emergency-confirmation__icon", `emergency-confirmation__icon--${tone}`),
|
|
1752
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: danger ? "alert-triangle" : "info" })
|
|
1753
|
+
}),
|
|
1754
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h5", {
|
|
1755
|
+
className: cls("emergency-confirmation__title"),
|
|
1756
|
+
id: titleId,
|
|
1757
|
+
children: title
|
|
1758
|
+
}),
|
|
1759
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1760
|
+
className: cls("emergency-confirmation__text"),
|
|
1761
|
+
children: text
|
|
1762
|
+
})
|
|
1763
|
+
]
|
|
1764
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1765
|
+
className: cls("emergency-confirmation__footer"),
|
|
1766
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1767
|
+
type: "button",
|
|
1768
|
+
className: cls("emergency-confirmation__button", "emergency-confirmation__button--cancel"),
|
|
1769
|
+
onClick: danger ? onCancelAbort : onCancelSimulation,
|
|
1770
|
+
children: danger ? copy.abortCancel : copy.simulateCancel
|
|
1771
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1772
|
+
type: "button",
|
|
1773
|
+
className: cls("emergency-confirmation__button", danger ? "emergency-confirmation__button--danger" : "emergency-confirmation__button--confirm"),
|
|
1774
|
+
onClick: danger ? onConfirmAbort : onConfirmSimulation,
|
|
1775
|
+
children: danger ? copy.abortConfirm : copy.simulateConfirm
|
|
1776
|
+
})]
|
|
1777
|
+
})]
|
|
1778
|
+
})
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
// src/react/hooks/useEscapeKey.ts
|
|
1783
|
+
function useEscapeKey(active, onEscape) {
|
|
1784
|
+
(0, react.useEffect)(() => {
|
|
1785
|
+
if (!active || typeof document === "undefined") return;
|
|
1786
|
+
const handleKeyDown = (event) => {
|
|
1787
|
+
if (event.key === "Escape") {
|
|
1788
|
+
event.stopPropagation();
|
|
1789
|
+
onEscape();
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1793
|
+
return () => {
|
|
1794
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1795
|
+
};
|
|
1796
|
+
}, [active, onEscape]);
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
// src/react/hooks/useFocusTrap.ts
|
|
1800
|
+
const FOCUSABLE_SELECTOR = [
|
|
1801
|
+
"a[href]",
|
|
1802
|
+
"button:not([disabled])",
|
|
1803
|
+
"input:not([disabled])",
|
|
1804
|
+
"select:not([disabled])",
|
|
1805
|
+
"textarea:not([disabled])",
|
|
1806
|
+
"[tabindex]:not([tabindex=\"-1\"])"
|
|
1807
|
+
].join(",");
|
|
1808
|
+
/**
|
|
1809
|
+
* Keeps keyboard focus inside the dialog while it is open and restores focus to
|
|
1810
|
+
* the element that opened it when it closes.
|
|
1811
|
+
*/
|
|
1812
|
+
function useFocusTrap(ref, active) {
|
|
1813
|
+
(0, react.useEffect)(() => {
|
|
1814
|
+
if (!active || typeof document === "undefined") return;
|
|
1815
|
+
const container = ref.current;
|
|
1816
|
+
if (!container) return;
|
|
1817
|
+
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
1818
|
+
const focusable = () => Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter((element) => !element.hasAttribute("hidden") && element.getAttribute("aria-hidden") !== "true");
|
|
1819
|
+
(focusable()[0] ?? container).focus({ preventScroll: true });
|
|
1820
|
+
const handleKeyDown = (event) => {
|
|
1821
|
+
if (event.key !== "Tab") return;
|
|
1822
|
+
const items = focusable();
|
|
1823
|
+
if (items.length === 0) {
|
|
1824
|
+
event.preventDefault();
|
|
1825
|
+
container.focus({ preventScroll: true });
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
const first = items[0];
|
|
1829
|
+
const last = items[items.length - 1];
|
|
1830
|
+
const current = document.activeElement;
|
|
1831
|
+
if (event.shiftKey && (current === first || !container.contains(current))) {
|
|
1832
|
+
event.preventDefault();
|
|
1833
|
+
if (last) last.focus({ preventScroll: true });
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
if (!event.shiftKey && (current === last || !container.contains(current)) && first) {
|
|
1837
|
+
event.preventDefault();
|
|
1838
|
+
first.focus({ preventScroll: true });
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
1842
|
+
return () => {
|
|
1843
|
+
document.removeEventListener("keydown", handleKeyDown, true);
|
|
1844
|
+
if (previouslyFocused?.isConnected) previouslyFocused.focus({ preventScroll: true });
|
|
1845
|
+
};
|
|
1846
|
+
}, [active, ref]);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
// src/react/screens/context.tsx
|
|
1850
|
+
const EmergencyScreenContext = (0, react.createContext)(null);
|
|
1851
|
+
function EmergencyScreenProvider({ children, initialScreen = "primary" }) {
|
|
1852
|
+
const [state, setState] = (0, react.useState)({
|
|
1853
|
+
screen: initialScreen,
|
|
1854
|
+
history: []
|
|
1855
|
+
});
|
|
1856
|
+
const navigate = (0, react.useCallback)((next) => {
|
|
1857
|
+
setState((current) => {
|
|
1858
|
+
if (current.screen === next) return current;
|
|
1859
|
+
return {
|
|
1860
|
+
screen: next,
|
|
1861
|
+
history: [...current.history, current.screen]
|
|
1862
|
+
};
|
|
1863
|
+
});
|
|
1864
|
+
}, []);
|
|
1865
|
+
const back = (0, react.useCallback)(() => {
|
|
1866
|
+
setState((current) => {
|
|
1867
|
+
const previous = current.history.at(-1);
|
|
1868
|
+
if (!previous) return current;
|
|
1869
|
+
return {
|
|
1870
|
+
screen: previous,
|
|
1871
|
+
history: current.history.slice(0, -1)
|
|
1872
|
+
};
|
|
1873
|
+
});
|
|
1874
|
+
}, []);
|
|
1875
|
+
const reset = (0, react.useCallback)(() => {
|
|
1876
|
+
setState((current) => {
|
|
1877
|
+
if (current.screen === "primary" && current.history.length === 0) return current;
|
|
1878
|
+
return {
|
|
1879
|
+
screen: "primary",
|
|
1880
|
+
history: []
|
|
1881
|
+
};
|
|
1882
|
+
});
|
|
1883
|
+
}, []);
|
|
1884
|
+
const value = (0, react.useMemo)(() => ({
|
|
1885
|
+
screen: state.screen,
|
|
1886
|
+
history: state.history,
|
|
1887
|
+
navigate,
|
|
1888
|
+
back,
|
|
1889
|
+
reset
|
|
1890
|
+
}), [
|
|
1891
|
+
back,
|
|
1892
|
+
navigate,
|
|
1893
|
+
reset,
|
|
1894
|
+
state.history,
|
|
1895
|
+
state.screen
|
|
1896
|
+
]);
|
|
1897
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenContext.Provider, {
|
|
1898
|
+
value,
|
|
1899
|
+
children
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
function useScreenNavigation() {
|
|
1903
|
+
const value = (0, react.useContext)(EmergencyScreenContext);
|
|
1904
|
+
if (!value) throw new Error("useScreenNavigation must be used inside EmergencyScreenProvider.");
|
|
1905
|
+
return value;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
// src/react/components/EmergencyHeader/index.tsx
|
|
1909
|
+
function EmergencyHeader({ titleId, onClose, title = copy.panelLabel, onBack, variant = "default" }) {
|
|
1910
|
+
const closeOnly = variant === "close-only";
|
|
1911
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
1912
|
+
className: cls("emergency-panel__header", closeOnly && "emergency-panel__header--close-only"),
|
|
1913
|
+
children: [
|
|
1914
|
+
onBack && !closeOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1915
|
+
type: "button",
|
|
1916
|
+
className: cls("emergency-panel__close-button"),
|
|
1917
|
+
"aria-label": copy.back,
|
|
1918
|
+
onClick: onBack,
|
|
1919
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
1920
|
+
name: "arrow-left",
|
|
1921
|
+
className: cls("emergency-panel__close-icon")
|
|
1922
|
+
})
|
|
1923
|
+
}) : null,
|
|
1924
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
1925
|
+
className: cls("emergency-panel__title", closeOnly && "emergency-panel__sr-only"),
|
|
1926
|
+
id: titleId,
|
|
1927
|
+
tabIndex: -1,
|
|
1928
|
+
children: title
|
|
1929
|
+
}),
|
|
1930
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1931
|
+
type: "button",
|
|
1932
|
+
className: cls("emergency-panel__close-button"),
|
|
1933
|
+
"aria-label": copy.close,
|
|
1934
|
+
onClick: onClose,
|
|
1935
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
1936
|
+
name: "close",
|
|
1937
|
+
className: cls("emergency-panel__close-icon")
|
|
1938
|
+
})
|
|
1939
|
+
})
|
|
1940
|
+
]
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
// src/react/screens/layout.tsx
|
|
1945
|
+
/**
|
|
1946
|
+
* Shared shell for every screen. The wrapper is `display: contents` so the
|
|
1947
|
+
* header, body and footer stay direct grid rows of the emergency panel.
|
|
1948
|
+
*/
|
|
1949
|
+
function EmergencyScreenLayout({ screen, titleId, header, footer, children, bodyClassName }) {
|
|
1950
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1951
|
+
className: cls("emergency-screen"),
|
|
1952
|
+
"data-screen": screen,
|
|
1953
|
+
children: [
|
|
1954
|
+
header,
|
|
1955
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
1956
|
+
className: cls("emergency-panel__body", bodyClassName ?? null),
|
|
1957
|
+
"aria-labelledby": titleId,
|
|
1958
|
+
children
|
|
1959
|
+
}),
|
|
1960
|
+
footer
|
|
1961
|
+
]
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
// src/react/screens/PlaceholderScreen.tsx
|
|
1966
|
+
/** Minimal in-design screen used to prove navigation before real designs land. */
|
|
1967
|
+
function PlaceholderScreen({ screen, titleId, title, description, onClose, onBack }) {
|
|
1968
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenLayout, {
|
|
1969
|
+
screen,
|
|
1970
|
+
titleId,
|
|
1971
|
+
header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyHeader, {
|
|
1972
|
+
titleId,
|
|
1973
|
+
title,
|
|
1974
|
+
onClose,
|
|
1975
|
+
onBack
|
|
1976
|
+
}),
|
|
1977
|
+
footer: null,
|
|
1978
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1979
|
+
className: cls("emergency-screen__placeholder"),
|
|
1980
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1981
|
+
className: cls("emergency-screen__placeholder-text"),
|
|
1982
|
+
children: description
|
|
1983
|
+
})
|
|
1984
|
+
})
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// src/react/screens/details/copy.ts
|
|
1989
|
+
const detailsCopy = {
|
|
1990
|
+
title: "Detalles",
|
|
1991
|
+
description: "Aquí podrás consultar el detalle de tus alertas disponibles. Esta pantalla estará disponible próximamente."
|
|
1992
|
+
};
|
|
1993
|
+
|
|
1994
|
+
// src/react/screens/details/index.tsx
|
|
1995
|
+
function DetailsScreen({ titleId, onClose }) {
|
|
1996
|
+
const { back } = useScreenNavigation();
|
|
1997
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaceholderScreen, {
|
|
1998
|
+
screen: "details",
|
|
1999
|
+
titleId,
|
|
2000
|
+
title: detailsCopy.title,
|
|
2001
|
+
description: detailsCopy.description,
|
|
2002
|
+
onClose: () => onClose("close"),
|
|
2003
|
+
onBack: back
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
// src/core/phone.ts
|
|
2008
|
+
const VENEZUELA_DIALLING_CODE = "+58";
|
|
2009
|
+
const VENEZUELAN_MOBILE_PATTERN = /^4\d{9}$/;
|
|
2010
|
+
function normalizeVenezuelanPhone(input) {
|
|
2011
|
+
return input.replace(/\D/g, "").replace(/^0+/, "");
|
|
2012
|
+
}
|
|
2013
|
+
function formatVenezuelanPhone(input) {
|
|
2014
|
+
const digits = normalizeVenezuelanPhone(input).slice(0, 10);
|
|
2015
|
+
if (digits.length <= 3) return digits;
|
|
2016
|
+
return `${digits.slice(0, 3)} ${digits.slice(3)}`;
|
|
2017
|
+
}
|
|
2018
|
+
function isValidVenezuelanPhone(input) {
|
|
2019
|
+
return VENEZUELAN_MOBILE_PATTERN.test(normalizeVenezuelanPhone(input));
|
|
2020
|
+
}
|
|
2021
|
+
function toVenezuelanE164(input) {
|
|
2022
|
+
const digits = normalizeVenezuelanPhone(input);
|
|
2023
|
+
if (!VENEZUELAN_MOBILE_PATTERN.test(digits)) return null;
|
|
2024
|
+
return `${"+58"}${digits}`;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
// src/react/components/EmergencyFooter/index.tsx
|
|
2028
|
+
function EmergencyFooter(props) {
|
|
2029
|
+
const { active, busy, aborting, feedbackVisible, showSimulation = true, emergencyDisabled = false, onActivate, onRequestAbort, onRequestSimulation } = props;
|
|
2030
|
+
if (active) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
|
|
2031
|
+
className: cls("emergency-panel__footer"),
|
|
2032
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2033
|
+
type: "button",
|
|
2034
|
+
className: cls("emergency-status__abort-btn"),
|
|
2035
|
+
"aria-label": copy.abort,
|
|
2036
|
+
disabled: aborting || feedbackVisible,
|
|
2037
|
+
onClick: onRequestAbort,
|
|
2038
|
+
children: [copy.abort, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "alert-triangle" })]
|
|
2039
|
+
})
|
|
2040
|
+
});
|
|
2041
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
|
|
2042
|
+
className: cls("emergency-panel__footer", !showSimulation && "emergency-panel__footer--single"),
|
|
2043
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2044
|
+
type: "button",
|
|
2045
|
+
className: cls("emergency-panel__button", "emergency-panel__button--emergency"),
|
|
2046
|
+
"aria-label": copy.emergencyAria,
|
|
2047
|
+
disabled: busy || feedbackVisible || emergencyDisabled,
|
|
2048
|
+
onClick: onActivate,
|
|
2049
|
+
children: [copy.emergency, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "emergency" })]
|
|
2050
|
+
}), showSimulation ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2051
|
+
type: "button",
|
|
2052
|
+
className: cls("emergency-panel__button", "emergency-panel__button--simulation"),
|
|
2053
|
+
"aria-label": copy.testAria,
|
|
2054
|
+
disabled: busy || feedbackVisible,
|
|
2055
|
+
onClick: onRequestSimulation,
|
|
2056
|
+
children: [copy.test, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "list-check" })]
|
|
2057
|
+
}) : null]
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
// src/react/screens/pre-emergency/copy.ts
|
|
2062
|
+
const preEmergencyCopy = {
|
|
2063
|
+
title: "Pre-emergencia",
|
|
2064
|
+
permissionNotice: "Debes autorizar todos los permisos de ubicación",
|
|
2065
|
+
phoneLabel: "Indique su número de teléfono",
|
|
2066
|
+
phonePlaceholder: "Ej. 0412 000 0000",
|
|
2067
|
+
areaCodeLabel: "Código de país",
|
|
2068
|
+
areaCode: "+58",
|
|
2069
|
+
invalidPhone: "Ingresa un número móvil venezolano válido. Ej. 412 1301234"
|
|
2070
|
+
};
|
|
2071
|
+
|
|
2072
|
+
// src/react/screens/pre-emergency/index.tsx
|
|
2073
|
+
function PreEmergencyScreen(props) {
|
|
2074
|
+
const { back } = useScreenNavigation();
|
|
2075
|
+
const phoneId = (0, react.useId)();
|
|
2076
|
+
const errorId = `${phoneId}-error`;
|
|
2077
|
+
const permissionId = `${phoneId}-permission`;
|
|
2078
|
+
const [digits, setDigits] = (0, react.useState)("");
|
|
2079
|
+
const [touched, setTouched] = (0, react.useState)(false);
|
|
2080
|
+
const valid = isValidVenezuelanPhone(digits);
|
|
2081
|
+
const invalid = touched && digits.length > 0 && !valid;
|
|
2082
|
+
const handleChange = (event) => {
|
|
2083
|
+
const next = normalizeVenezuelanPhone(event.target.value).slice(0, 10);
|
|
2084
|
+
setDigits(next);
|
|
2085
|
+
};
|
|
2086
|
+
const handleSubmit = () => {
|
|
2087
|
+
setTouched(true);
|
|
2088
|
+
if (!valid) return;
|
|
2089
|
+
const phone = toVenezuelanE164(digits);
|
|
2090
|
+
if (phone === null) return;
|
|
2091
|
+
props.onSetContactPhone(phone);
|
|
2092
|
+
props.onActivate();
|
|
2093
|
+
};
|
|
2094
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenLayout, {
|
|
2095
|
+
screen: "pre-emergency",
|
|
2096
|
+
titleId: props.titleId,
|
|
2097
|
+
bodyClassName: "emergency-panel__body--pre-emergency",
|
|
2098
|
+
header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyHeader, {
|
|
2099
|
+
titleId: props.titleId,
|
|
2100
|
+
title: preEmergencyCopy.title,
|
|
2101
|
+
onClose: () => props.onClose("close"),
|
|
2102
|
+
onBack: back
|
|
2103
|
+
}),
|
|
2104
|
+
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyFooter, {
|
|
2105
|
+
active: props.active,
|
|
2106
|
+
busy: props.busy,
|
|
2107
|
+
aborting: props.aborting,
|
|
2108
|
+
feedbackVisible: props.feedbackVisible,
|
|
2109
|
+
emergencyDisabled: !valid,
|
|
2110
|
+
showSimulation: false,
|
|
2111
|
+
onActivate: handleSubmit,
|
|
2112
|
+
onRequestAbort: props.onRequestAbort,
|
|
2113
|
+
onRequestSimulation: props.onRequestSimulation
|
|
2114
|
+
}),
|
|
2115
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2116
|
+
className: cls("emergency-pre-emergency"),
|
|
2117
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2118
|
+
role: "note",
|
|
2119
|
+
"aria-labelledby": permissionId,
|
|
2120
|
+
className: cls("emergency-pre-emergency__notice"),
|
|
2121
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
2122
|
+
name: "map-pin",
|
|
2123
|
+
className: cls("emergency-pre-emergency__notice-icon")
|
|
2124
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2125
|
+
id: permissionId,
|
|
2126
|
+
className: cls("emergency-pre-emergency__notice-text"),
|
|
2127
|
+
children: preEmergencyCopy.permissionNotice
|
|
2128
|
+
})]
|
|
2129
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
2130
|
+
className: cls("emergency-pre-emergency__form"),
|
|
2131
|
+
noValidate: true,
|
|
2132
|
+
onSubmit: (event) => {
|
|
2133
|
+
event.preventDefault();
|
|
2134
|
+
handleSubmit();
|
|
2135
|
+
},
|
|
2136
|
+
onKeyDown: (event) => {
|
|
2137
|
+
if (event.key === "Enter") {
|
|
2138
|
+
event.preventDefault();
|
|
2139
|
+
handleSubmit();
|
|
2140
|
+
}
|
|
2141
|
+
},
|
|
2142
|
+
children: [
|
|
2143
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
2144
|
+
htmlFor: phoneId,
|
|
2145
|
+
className: cls("emergency-pre-emergency__label"),
|
|
2146
|
+
children: preEmergencyCopy.phoneLabel
|
|
2147
|
+
}),
|
|
2148
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2149
|
+
className: cls("emergency-pre-emergency__phone-row"),
|
|
2150
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2151
|
+
type: "tel",
|
|
2152
|
+
"aria-label": preEmergencyCopy.areaCodeLabel,
|
|
2153
|
+
className: cls("emergency-pre-emergency__input", "emergency-pre-emergency__input--area-code", valid && "emergency-pre-emergency__input--valid"),
|
|
2154
|
+
value: preEmergencyCopy.areaCode,
|
|
2155
|
+
disabled: true,
|
|
2156
|
+
readOnly: true
|
|
2157
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2158
|
+
id: phoneId,
|
|
2159
|
+
type: "tel",
|
|
2160
|
+
inputMode: "tel",
|
|
2161
|
+
autoComplete: "tel-national",
|
|
2162
|
+
placeholder: preEmergencyCopy.phonePlaceholder,
|
|
2163
|
+
className: cls("emergency-pre-emergency__input", "emergency-pre-emergency__input--number", valid && "emergency-pre-emergency__input--valid", invalid && "emergency-pre-emergency__input--invalid"),
|
|
2164
|
+
value: formatVenezuelanPhone(digits),
|
|
2165
|
+
"aria-invalid": invalid,
|
|
2166
|
+
"aria-describedby": invalid ? errorId : void 0,
|
|
2167
|
+
onChange: handleChange,
|
|
2168
|
+
onBlur: () => setTouched(true)
|
|
2169
|
+
})]
|
|
2170
|
+
}),
|
|
2171
|
+
invalid ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2172
|
+
id: errorId,
|
|
2173
|
+
role: "alert",
|
|
2174
|
+
className: cls("emergency-pre-emergency__error"),
|
|
2175
|
+
children: preEmergencyCopy.invalidPhone
|
|
2176
|
+
}) : null
|
|
2177
|
+
]
|
|
2178
|
+
})]
|
|
2179
|
+
})
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
// src/react/components/icons/paramedical-mark.tsx
|
|
2184
|
+
/**
|
|
2185
|
+
* Neutral inline illustration used by the idle panel.
|
|
2186
|
+
*/
|
|
2187
|
+
function ParamedicalMark({ className, title }) {
|
|
2188
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
2189
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2190
|
+
version: "1.0",
|
|
2191
|
+
viewBox: "0 0 192 192",
|
|
2192
|
+
width: "192",
|
|
2193
|
+
height: "192",
|
|
2194
|
+
id: "Star of life",
|
|
2195
|
+
className,
|
|
2196
|
+
"aria-label": title,
|
|
2197
|
+
children: [
|
|
2198
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { id: "defs2886" }),
|
|
2199
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
2200
|
+
id: "cross",
|
|
2201
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2202
|
+
d: "m 74,133 0,52 44,0 0,-52 44,26 22,-38 L 140,96 184,70 162,32 117,58 117,7 74,7 74,58 30,32 8,70 52,96 8,121 30,159 z",
|
|
2203
|
+
id: "outline",
|
|
2204
|
+
style: {
|
|
2205
|
+
fill: "none",
|
|
2206
|
+
stroke: "#3333bb",
|
|
2207
|
+
strokeWidth: 6
|
|
2208
|
+
}
|
|
2209
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2210
|
+
d: "m 74,133 0,52 44,0 0,-52 44,26 22,-38 L 140,96 184,70 162,32 117,58 117,7 74,7 74,58 30,32 8,70 52,96 8,121 30,159 z",
|
|
2211
|
+
id: "inner",
|
|
2212
|
+
style: {
|
|
2213
|
+
fill: "#0000bb",
|
|
2214
|
+
fillRule: "evenodd",
|
|
2215
|
+
stroke: "#ffffff",
|
|
2216
|
+
strokeWidth: 2
|
|
2217
|
+
}
|
|
2218
|
+
})]
|
|
2219
|
+
}),
|
|
2220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
2221
|
+
id: "symbols",
|
|
2222
|
+
style: {
|
|
2223
|
+
fill: "#ffffff",
|
|
2224
|
+
fillRule: "evenodd",
|
|
2225
|
+
stroke: "#3333bb",
|
|
2226
|
+
strokeWidth: 2
|
|
2227
|
+
},
|
|
2228
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2229
|
+
d: "m 93,166 c 0,7 6,7 6,0 l 3,-138 c 0,-8 -12,-8 -12,0 l 3,135 0,3 z",
|
|
2230
|
+
id: "rod"
|
|
2231
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
2232
|
+
id: "snake",
|
|
2233
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2234
|
+
d: "m 100,153 c 7,4 3,15 -3,15 2,-5 3,-9 3,-15 z m 1,-40 c 10,9 4,22 -3,26 -6,3 -6,7 -6,15 -9,-10 -4,-19 4,-24 5,-4 5,-10 5,-17 z m 1,-30 c 0,11 -17,14 -17,22 0,3 1,9 6,12 0,-11 9,-12 15,-18 7,-7 7,-19 -4,-28 0,4 0,8 0,12 z M 90,77 C 80,69 76,55 80,46 c 3,-10 20,-11 20,-3 0,8 -20,3 -13,16 l 3,5 0,13 z",
|
|
2235
|
+
id: "body"
|
|
2236
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2237
|
+
d: "m 95,43 c 7,-3 -7,-3 0,0 z",
|
|
2238
|
+
id: "eye",
|
|
2239
|
+
style: {
|
|
2240
|
+
fill: "#3333bb",
|
|
2241
|
+
fillRule: "evenodd",
|
|
2242
|
+
stroke: "none"
|
|
2243
|
+
}
|
|
2244
|
+
})]
|
|
2245
|
+
})]
|
|
2246
|
+
})
|
|
2247
|
+
]
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
|
|
1712
2251
|
// src/react/components/MessageSurface/index.tsx
|
|
1713
2252
|
function MessageSurface(props) {
|
|
1714
2253
|
const { variant, icon, title, text, details, className, children } = props;
|
|
@@ -2033,237 +2572,410 @@ function EmergencyStatusPanel({ responders, refreshing, locale, onRefresh }) {
|
|
|
2033
2572
|
});
|
|
2034
2573
|
}
|
|
2035
2574
|
|
|
2575
|
+
// src/react/screens/primary/copy.ts
|
|
2576
|
+
const primaryCopy = {
|
|
2577
|
+
availabilityTitle: "Alertas Disponibles",
|
|
2578
|
+
recharge: "Recargar",
|
|
2579
|
+
details: "Detalles",
|
|
2580
|
+
roundSingular: "ronda disponible",
|
|
2581
|
+
roundPlural: "rondas disponibles"
|
|
2582
|
+
};
|
|
2583
|
+
/** Singular/plural label for the remaining rounds. */
|
|
2584
|
+
function roundsUnit(rounds) {
|
|
2585
|
+
return rounds === 1 ? primaryCopy.roundSingular : primaryCopy.roundPlural;
|
|
2586
|
+
}
|
|
2587
|
+
function formatRounds(rounds) {
|
|
2588
|
+
return `${rounds} ${roundsUnit(rounds)}`;
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
// src/react/screens/primary/data.ts
|
|
2592
|
+
/**
|
|
2593
|
+
* Derives the remaining alert rounds from available messages and designated
|
|
2594
|
+
* responders. Invalid or non-positive input collapses to the minimum of one
|
|
2595
|
+
* round instead of producing `Infinity`, `NaN` or a negative value.
|
|
2596
|
+
*/
|
|
2597
|
+
function calculateRounds(messages, responders) {
|
|
2598
|
+
if (!Number.isFinite(messages) || !Number.isFinite(responders)) return 1;
|
|
2599
|
+
const availableMessages = Math.floor(messages);
|
|
2600
|
+
const designatedResponders = Math.floor(responders);
|
|
2601
|
+
if (availableMessages <= 0 || designatedResponders <= 0) return 1;
|
|
2602
|
+
return Math.max(1, Math.floor(availableMessages / designatedResponders));
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
// src/react/screens/primary/Availability.tsx
|
|
2606
|
+
function Availability({ onRecharge, onDetails }) {
|
|
2607
|
+
const rounds = calculateRounds(100, 3);
|
|
2608
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2609
|
+
className: cls("emergency-availability"),
|
|
2610
|
+
"aria-label": primaryCopy.availabilityTitle,
|
|
2611
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2612
|
+
type: "button",
|
|
2613
|
+
className: cls("emergency-availability__recharge"),
|
|
2614
|
+
onClick: onRecharge,
|
|
2615
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "credit-card-plus" }), primaryCopy.recharge]
|
|
2616
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2617
|
+
className: cls("emergency-availability__card"),
|
|
2618
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2619
|
+
className: cls("emergency-availability__card-header"),
|
|
2620
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2621
|
+
className: cls("emergency-availability__card-title"),
|
|
2622
|
+
children: primaryCopy.availabilityTitle
|
|
2623
|
+
})
|
|
2624
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2625
|
+
className: cls("emergency-availability__card-body"),
|
|
2626
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2627
|
+
className: cls("emergency-availability__rounds-group"),
|
|
2628
|
+
"aria-label": formatRounds(rounds),
|
|
2629
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2630
|
+
className: cls("emergency-availability__rounds"),
|
|
2631
|
+
children: rounds
|
|
2632
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2633
|
+
className: cls("emergency-availability__label"),
|
|
2634
|
+
children: roundsUnit(rounds)
|
|
2635
|
+
})]
|
|
2636
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2637
|
+
type: "button",
|
|
2638
|
+
className: cls("emergency-availability__details"),
|
|
2639
|
+
onClick: onDetails,
|
|
2640
|
+
children: primaryCopy.details
|
|
2641
|
+
})]
|
|
2642
|
+
})]
|
|
2643
|
+
})]
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2036
2647
|
// src/react/components/EmergencyBody/index.tsx
|
|
2037
2648
|
function EmergencyBody(props) {
|
|
2038
|
-
const { active, responders, refreshing, loading, locale, geolocationError, activationError, error, abortResult, simulationResult, onRefresh, onRetry, onDismissFeedback } = props;
|
|
2649
|
+
const { active, responders, refreshing, loading, locale, geolocationError, activationError, error, abortResult, simulationResult, onRefresh, onRetry, onDismissFeedback, onRecharge, onDetails } = props;
|
|
2039
2650
|
const showingFeedback = geolocationError !== null || Boolean(activationError) || abortResult !== null || simulationResult !== null;
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
}) : null,
|
|
2049
|
-
active || loading || showingFeedback ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2050
|
-
className: cls("emergency-panel__body-title-container"),
|
|
2051
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
2052
|
-
className: cls("emergency-panel__body-title"),
|
|
2053
|
-
children: copy.question
|
|
2651
|
+
const idle = !active && !loading && !showingFeedback && error === null;
|
|
2652
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2653
|
+
className: cls("emergency-panel__body-split", idle && "emergency-panel__body-split--with-availability"),
|
|
2654
|
+
children: [idle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2655
|
+
className: cls("emergency-panel__availability-region"),
|
|
2656
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Availability, {
|
|
2657
|
+
onRecharge,
|
|
2658
|
+
onDetails
|
|
2054
2659
|
})
|
|
2660
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", {
|
|
2661
|
+
className: cls("emergency-panel__divider"),
|
|
2662
|
+
"aria-hidden": "true"
|
|
2663
|
+
})] }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2664
|
+
className: cls("emergency-panel__prompt-region"),
|
|
2665
|
+
children: [
|
|
2666
|
+
!loading && !showingFeedback ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2667
|
+
className: cls("sos-img__container"),
|
|
2668
|
+
id: "sos-img__container",
|
|
2669
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParamedicalMark, {
|
|
2670
|
+
className: cls("sos-img"),
|
|
2671
|
+
title: copy.illustrationAlt
|
|
2672
|
+
})
|
|
2673
|
+
}) : null,
|
|
2674
|
+
active || loading || showingFeedback ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2675
|
+
className: cls("emergency-panel__body-title-container"),
|
|
2676
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
2677
|
+
className: cls("emergency-panel__body-title"),
|
|
2678
|
+
children: copy.question
|
|
2679
|
+
})
|
|
2680
|
+
}),
|
|
2681
|
+
active && !showingFeedback ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyStatusPanel, {
|
|
2682
|
+
responders,
|
|
2683
|
+
refreshing,
|
|
2684
|
+
locale,
|
|
2685
|
+
onRefresh
|
|
2686
|
+
}) : null,
|
|
2687
|
+
loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyLoading, {}) : null,
|
|
2688
|
+
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyError, {
|
|
2689
|
+
error,
|
|
2690
|
+
onRetry
|
|
2691
|
+
}) : null,
|
|
2692
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyFeedback, {
|
|
2693
|
+
abortResult,
|
|
2694
|
+
simulationResult,
|
|
2695
|
+
geolocationError,
|
|
2696
|
+
activationError,
|
|
2697
|
+
onDismiss: onDismissFeedback
|
|
2698
|
+
})
|
|
2699
|
+
]
|
|
2700
|
+
})]
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
// src/react/screens/primary/index.tsx
|
|
2705
|
+
function PrimaryScreen(props) {
|
|
2706
|
+
const { navigate } = useScreenNavigation();
|
|
2707
|
+
const idle = !props.active && !props.loading && !props.feedbackVisible && props.error === null;
|
|
2708
|
+
const needsContactPhone = props.contactPhone === null;
|
|
2709
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenLayout, {
|
|
2710
|
+
screen: "primary",
|
|
2711
|
+
titleId: props.titleId,
|
|
2712
|
+
header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyHeader, {
|
|
2713
|
+
titleId: props.titleId,
|
|
2714
|
+
variant: idle ? "close-only" : "default",
|
|
2715
|
+
onClose: () => props.onClose("close")
|
|
2055
2716
|
}),
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2717
|
+
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyFooter, {
|
|
2718
|
+
active: props.active,
|
|
2719
|
+
busy: props.busy,
|
|
2720
|
+
aborting: props.aborting,
|
|
2721
|
+
feedbackVisible: props.feedbackVisible,
|
|
2722
|
+
onActivate: needsContactPhone ? () => navigate("pre-emergency") : props.onActivate,
|
|
2723
|
+
onRequestAbort: props.onRequestAbort,
|
|
2724
|
+
onRequestSimulation: props.onRequestSimulation
|
|
2725
|
+
}),
|
|
2726
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyBody, {
|
|
2727
|
+
active: props.active,
|
|
2728
|
+
responders: props.responders,
|
|
2729
|
+
refreshing: props.refreshing,
|
|
2730
|
+
loading: props.loading,
|
|
2731
|
+
locale: props.locale,
|
|
2732
|
+
geolocationError: props.geolocationError,
|
|
2733
|
+
activationError: props.activationError,
|
|
2734
|
+
error: props.error,
|
|
2735
|
+
abortResult: props.abortResult,
|
|
2736
|
+
simulationResult: props.simulationResult,
|
|
2737
|
+
onRefresh: props.onRefresh,
|
|
2738
|
+
onRetry: props.onRetry,
|
|
2739
|
+
onDismissFeedback: props.onDismissFeedback,
|
|
2740
|
+
onRecharge: () => navigate("pricing"),
|
|
2741
|
+
onDetails: () => navigate("details")
|
|
2073
2742
|
})
|
|
2074
|
-
|
|
2743
|
+
});
|
|
2075
2744
|
}
|
|
2076
2745
|
|
|
2077
|
-
// src/react/
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2746
|
+
// src/react/screens/pricing/copy.ts
|
|
2747
|
+
const pricingCopy = {
|
|
2748
|
+
title: "Recargar",
|
|
2749
|
+
heading: "Elige tu paquete",
|
|
2750
|
+
subtitle: "Alertas de WhatsApp para tus contactos",
|
|
2751
|
+
bestValue: "MEJOR VALOR",
|
|
2752
|
+
choose: "Seleccionar",
|
|
2753
|
+
chosen: "Seleccionado",
|
|
2754
|
+
whatsapp: "de WhatsApp",
|
|
2755
|
+
rounds: "rondas de alerta",
|
|
2756
|
+
perMessage: "IVA Incluido",
|
|
2757
|
+
footnote: "Rondas calculadas con 3 contactos de emergencia. Válidas para pruebas y emergencias."
|
|
2758
|
+
};
|
|
2759
|
+
|
|
2760
|
+
// src/react/screens/pricing/data.ts
|
|
2761
|
+
/**
|
|
2762
|
+
* Local demo catalog. Prices and per-message labels are literal values from the
|
|
2763
|
+
* mock; they are not derived from the package totals.
|
|
2764
|
+
*/
|
|
2765
|
+
const PRICING_PACKAGES = [{
|
|
2766
|
+
id: "package-1",
|
|
2767
|
+
label: "PAQUETE 1",
|
|
2768
|
+
messages: 100,
|
|
2769
|
+
priceLabel: "$7",
|
|
2770
|
+
priceCaption: "IVA incluído",
|
|
2771
|
+
perMessageLabel: "$0.07",
|
|
2772
|
+
highlighted: false
|
|
2773
|
+
}, {
|
|
2774
|
+
id: "package-2",
|
|
2775
|
+
label: "PAQUETE 2",
|
|
2776
|
+
messages: 200,
|
|
2777
|
+
priceLabel: "12$",
|
|
2778
|
+
priceCaption: "IVA incluído",
|
|
2779
|
+
perMessageLabel: "$0.06",
|
|
2780
|
+
highlighted: true,
|
|
2781
|
+
badge: "MEJOR VALOR"
|
|
2782
|
+
}];
|
|
2783
|
+
/** Derives the alert rounds a package provides for the demo responder count. */
|
|
2784
|
+
function packageRounds(pkg) {
|
|
2785
|
+
return calculateRounds(pkg.messages, 3);
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
// src/react/screens/pricing/PackageCard.tsx
|
|
2789
|
+
function PackageCard({ pkg, selected, onSelect }) {
|
|
2790
|
+
const labelId = (0, react.useId)();
|
|
2791
|
+
const rounds = packageRounds(pkg);
|
|
2792
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2793
|
+
className: cls("emergency-pricing__package", pkg.highlighted && "emergency-pricing__package--highlighted"),
|
|
2794
|
+
"aria-labelledby": labelId,
|
|
2795
|
+
"data-selected": selected ? "true" : void 0,
|
|
2796
|
+
children: [
|
|
2797
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2798
|
+
className: cls("emergency-pricing__package-header"),
|
|
2799
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2800
|
+
className: cls("emergency-pricing__package-label"),
|
|
2801
|
+
id: labelId,
|
|
2802
|
+
children: pkg.label
|
|
2803
|
+
}), pkg.badge ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2804
|
+
className: cls("emergency-pricing__badge"),
|
|
2805
|
+
children: pkg.badge
|
|
2806
|
+
}) : null]
|
|
2807
|
+
}),
|
|
2808
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2809
|
+
className: cls("emergency-pricing__price-row"),
|
|
2810
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h4", {
|
|
2811
|
+
className: cls("emergency-pricing__package-name"),
|
|
2812
|
+
children: [pkg.messages, " alertas"]
|
|
2813
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2814
|
+
className: cls("emergency-pricing__package-caption"),
|
|
2815
|
+
children: pricingCopy.whatsapp
|
|
2816
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2817
|
+
className: cls("emergency-pricing__price-meta"),
|
|
2818
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2819
|
+
className: cls("emergency-pricing__price"),
|
|
2820
|
+
children: pkg.priceLabel
|
|
2821
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2822
|
+
className: cls("emergency-pricing__price-note"),
|
|
2823
|
+
children: [pkg.priceCaption, pkg.priceNote ? ` ${pkg.priceNote}` : null]
|
|
2824
|
+
})]
|
|
2825
|
+
})]
|
|
2826
|
+
}),
|
|
2827
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2828
|
+
className: cls("emergency-pricing__stats"),
|
|
2101
2829
|
children: [
|
|
2102
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2103
|
-
className: cls("emergency-
|
|
2104
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2830
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2831
|
+
className: cls("emergency-pricing__stat"),
|
|
2832
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2833
|
+
className: cls("emergency-pricing__stat-value"),
|
|
2834
|
+
children: rounds
|
|
2835
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2836
|
+
className: cls("emergency-pricing__stat-label"),
|
|
2837
|
+
children: pricingCopy.rounds
|
|
2838
|
+
})]
|
|
2105
2839
|
}),
|
|
2106
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
2107
|
-
className: cls("emergency-
|
|
2108
|
-
|
|
2109
|
-
children: title
|
|
2840
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2841
|
+
className: cls("emergency-pricing__stat-divider"),
|
|
2842
|
+
"aria-hidden": "true"
|
|
2110
2843
|
}),
|
|
2111
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2112
|
-
className: cls("emergency-
|
|
2113
|
-
children:
|
|
2844
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2845
|
+
className: cls("emergency-pricing__stat"),
|
|
2846
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2847
|
+
className: cls("emergency-pricing__stat-value"),
|
|
2848
|
+
children: pkg.perMessageLabel
|
|
2849
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2850
|
+
className: cls("emergency-pricing__stat-label"),
|
|
2851
|
+
children: pricingCopy.perMessage
|
|
2852
|
+
})]
|
|
2114
2853
|
})
|
|
2115
2854
|
]
|
|
2116
|
-
}),
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
})]
|
|
2130
|
-
})
|
|
2855
|
+
}),
|
|
2856
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2857
|
+
className: cls("emergency-pricing__package-footnote"),
|
|
2858
|
+
children: pricingCopy.footnote
|
|
2859
|
+
}),
|
|
2860
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2861
|
+
type: "button",
|
|
2862
|
+
className: cls("emergency-pricing__select"),
|
|
2863
|
+
"aria-pressed": selected,
|
|
2864
|
+
onClick: () => onSelect(pkg.id),
|
|
2865
|
+
children: selected ? pricingCopy.chosen : pricingCopy.choose
|
|
2866
|
+
})
|
|
2867
|
+
]
|
|
2131
2868
|
});
|
|
2132
2869
|
}
|
|
2133
2870
|
|
|
2134
|
-
// src/react/
|
|
2135
|
-
function
|
|
2136
|
-
const {
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2871
|
+
// src/react/screens/pricing/index.tsx
|
|
2872
|
+
function PricingScreen(props) {
|
|
2873
|
+
const { back } = useScreenNavigation();
|
|
2874
|
+
const [selected, setSelected] = (0, react.useState)(null);
|
|
2875
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenLayout, {
|
|
2876
|
+
screen: "pricing",
|
|
2877
|
+
titleId: props.titleId,
|
|
2878
|
+
bodyClassName: "emergency-panel__body--pricing",
|
|
2879
|
+
header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyHeader, {
|
|
2880
|
+
titleId: props.titleId,
|
|
2881
|
+
title: pricingCopy.title,
|
|
2882
|
+
onClose: () => props.onClose("close"),
|
|
2883
|
+
onBack: back
|
|
2884
|
+
}),
|
|
2885
|
+
footer: null,
|
|
2886
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2887
|
+
className: cls("emergency-pricing"),
|
|
2888
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2889
|
+
className: cls("emergency-pricing__heading"),
|
|
2890
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2891
|
+
className: cls("emergency-pricing__titles"),
|
|
2892
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2893
|
+
className: cls("emergency-pricing__title"),
|
|
2894
|
+
children: pricingCopy.heading
|
|
2895
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2896
|
+
className: cls("emergency-pricing__subtitle"),
|
|
2897
|
+
children: pricingCopy.subtitle
|
|
2898
|
+
})]
|
|
2899
|
+
})
|
|
2900
|
+
}), PRICING_PACKAGES.map((pkg) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PackageCard, {
|
|
2901
|
+
pkg,
|
|
2902
|
+
selected: selected === pkg.id,
|
|
2903
|
+
onSelect: setSelected
|
|
2904
|
+
}, pkg.id))]
|
|
2146
2905
|
})
|
|
2147
2906
|
});
|
|
2148
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
|
|
2149
|
-
className: cls("emergency-panel__footer"),
|
|
2150
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2151
|
-
type: "button",
|
|
2152
|
-
className: cls("emergency-panel__button", "emergency-panel__button--emergency"),
|
|
2153
|
-
"aria-label": copy.emergencyAria,
|
|
2154
|
-
disabled: busy || feedbackVisible,
|
|
2155
|
-
onClick: onActivate,
|
|
2156
|
-
children: [copy.emergency, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "emergency" })]
|
|
2157
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2158
|
-
type: "button",
|
|
2159
|
-
className: cls("emergency-panel__button", "emergency-panel__button--simulation"),
|
|
2160
|
-
"aria-label": copy.testAria,
|
|
2161
|
-
disabled: busy || feedbackVisible,
|
|
2162
|
-
onClick: onRequestSimulation,
|
|
2163
|
-
children: [copy.test, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "list-check" })]
|
|
2164
|
-
})]
|
|
2165
|
-
});
|
|
2166
2907
|
}
|
|
2167
2908
|
|
|
2168
|
-
// src/react/
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2177
|
-
type: "button",
|
|
2178
|
-
className: cls("emergency-panel__close-button"),
|
|
2179
|
-
"aria-label": copy.close,
|
|
2180
|
-
onClick: onClose,
|
|
2181
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
2182
|
-
name: "close",
|
|
2183
|
-
className: cls("emergency-panel__close-icon")
|
|
2184
|
-
})
|
|
2185
|
-
})]
|
|
2186
|
-
});
|
|
2187
|
-
}
|
|
2909
|
+
// src/react/screens/registry.ts
|
|
2910
|
+
/** Every screen the panel can render. Add one entry to add a screen. */
|
|
2911
|
+
const screenRegistry = {
|
|
2912
|
+
primary: PrimaryScreen,
|
|
2913
|
+
"pre-emergency": PreEmergencyScreen,
|
|
2914
|
+
pricing: PricingScreen,
|
|
2915
|
+
details: DetailsScreen
|
|
2916
|
+
};
|
|
2188
2917
|
|
|
2189
|
-
// src/react/
|
|
2190
|
-
function
|
|
2918
|
+
// src/react/components/EmergencyPanel/index.tsx
|
|
2919
|
+
function ActiveScreen({ screenProps, open, forcePrimary }) {
|
|
2920
|
+
const { screen, reset } = useScreenNavigation();
|
|
2921
|
+
const shouldReset = !open || forcePrimary;
|
|
2922
|
+
const effectiveScreen = shouldReset ? "primary" : screen;
|
|
2923
|
+
const previousOpen = (0, react.useRef)(open);
|
|
2924
|
+
const previousScreen = (0, react.useRef)(effectiveScreen);
|
|
2191
2925
|
(0, react.useEffect)(() => {
|
|
2192
|
-
if (
|
|
2193
|
-
|
|
2194
|
-
if (event.key === "Escape") {
|
|
2195
|
-
event.stopPropagation();
|
|
2196
|
-
onEscape();
|
|
2197
|
-
}
|
|
2198
|
-
};
|
|
2199
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
2200
|
-
return () => {
|
|
2201
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
2202
|
-
};
|
|
2203
|
-
}, [active, onEscape]);
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
// src/react/hooks/useFocusTrap.ts
|
|
2207
|
-
const FOCUSABLE_SELECTOR = [
|
|
2208
|
-
"a[href]",
|
|
2209
|
-
"button:not([disabled])",
|
|
2210
|
-
"input:not([disabled])",
|
|
2211
|
-
"select:not([disabled])",
|
|
2212
|
-
"textarea:not([disabled])",
|
|
2213
|
-
"[tabindex]:not([tabindex=\"-1\"])"
|
|
2214
|
-
].join(",");
|
|
2215
|
-
/**
|
|
2216
|
-
* Keeps keyboard focus inside the dialog while it is open and restores focus to
|
|
2217
|
-
* the element that opened it when it closes.
|
|
2218
|
-
*/
|
|
2219
|
-
function useFocusTrap(ref, active) {
|
|
2926
|
+
if (shouldReset) reset();
|
|
2927
|
+
}, [reset, shouldReset]);
|
|
2220
2928
|
(0, react.useEffect)(() => {
|
|
2221
|
-
|
|
2222
|
-
const
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
(
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
}
|
|
2235
|
-
const first = items[0];
|
|
2236
|
-
const last = items[items.length - 1];
|
|
2237
|
-
const current = document.activeElement;
|
|
2238
|
-
if (event.shiftKey && (current === first || !container.contains(current))) {
|
|
2239
|
-
event.preventDefault();
|
|
2240
|
-
if (last) last.focus({ preventScroll: true });
|
|
2241
|
-
return;
|
|
2242
|
-
}
|
|
2243
|
-
if (!event.shiftKey && current === last && first) {
|
|
2244
|
-
event.preventDefault();
|
|
2245
|
-
first.focus({ preventScroll: true });
|
|
2246
|
-
}
|
|
2247
|
-
};
|
|
2248
|
-
document.addEventListener("keydown", handleKeyDown, true);
|
|
2249
|
-
return () => {
|
|
2250
|
-
document.removeEventListener("keydown", handleKeyDown, true);
|
|
2251
|
-
if (previouslyFocused?.isConnected) previouslyFocused.focus({ preventScroll: true });
|
|
2252
|
-
};
|
|
2253
|
-
}, [active, ref]);
|
|
2929
|
+
const wasOpen = previousOpen.current;
|
|
2930
|
+
const previousEffectiveScreen = previousScreen.current;
|
|
2931
|
+
previousOpen.current = open;
|
|
2932
|
+
previousScreen.current = effectiveScreen;
|
|
2933
|
+
if (!open || !wasOpen || previousEffectiveScreen === effectiveScreen) return;
|
|
2934
|
+
document.getElementById(screenProps.titleId)?.focus({ preventScroll: true });
|
|
2935
|
+
}, [
|
|
2936
|
+
effectiveScreen,
|
|
2937
|
+
open,
|
|
2938
|
+
screenProps.titleId
|
|
2939
|
+
]);
|
|
2940
|
+
const Screen = screenRegistry[effectiveScreen];
|
|
2941
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Screen, { ...screenProps });
|
|
2254
2942
|
}
|
|
2255
|
-
|
|
2256
|
-
// src/react/components/EmergencyPanel/index.tsx
|
|
2257
2943
|
function EmergencyPanel(props) {
|
|
2258
|
-
const { open, theme, active, busy, aborting, loading, locale, responders, refreshing, geolocationError, activationError, error, abortResult, simulationResult, abortConfirmation, simulationConfirmation, onClose, onActivate, onRefresh, onRetry, onDismissFeedback, onRequestAbort, onRequestSimulation, onCancelAbort, onCancelSimulation, onConfirmAbort, onConfirmSimulation } = props;
|
|
2944
|
+
const { open, theme, active, busy, aborting, loading, locale, responders, refreshing, geolocationError, contactPhone, activationError, error, abortResult, simulationResult, abortConfirmation, simulationConfirmation, onClose, onActivate, onRefresh, onRetry, onDismissFeedback, onRequestAbort, onRequestSimulation, onCancelAbort, onCancelSimulation, onConfirmAbort, onConfirmSimulation, onSetContactPhone } = props;
|
|
2259
2945
|
const titleId = (0, react.useId)();
|
|
2260
2946
|
const dialogRef = (0, react.useRef)(null);
|
|
2261
2947
|
const feedbackVisible = geolocationError !== null || Boolean(activationError) || abortResult !== null || simulationResult !== null;
|
|
2948
|
+
const forcePrimary = active || loading || error !== null || feedbackVisible;
|
|
2262
2949
|
const closeOnEscape = (0, react.useCallback)(() => {
|
|
2263
2950
|
onClose("escape");
|
|
2264
2951
|
}, [onClose]);
|
|
2265
2952
|
useFocusTrap(dialogRef, open);
|
|
2266
2953
|
useEscapeKey(open, closeOnEscape);
|
|
2954
|
+
const screenProps = {
|
|
2955
|
+
titleId,
|
|
2956
|
+
active,
|
|
2957
|
+
busy,
|
|
2958
|
+
aborting,
|
|
2959
|
+
loading,
|
|
2960
|
+
locale,
|
|
2961
|
+
responders,
|
|
2962
|
+
refreshing,
|
|
2963
|
+
geolocationError,
|
|
2964
|
+
activationError,
|
|
2965
|
+
error,
|
|
2966
|
+
abortResult,
|
|
2967
|
+
simulationResult,
|
|
2968
|
+
feedbackVisible,
|
|
2969
|
+
contactPhone,
|
|
2970
|
+
onClose,
|
|
2971
|
+
onActivate,
|
|
2972
|
+
onRefresh,
|
|
2973
|
+
onRetry,
|
|
2974
|
+
onDismissFeedback,
|
|
2975
|
+
onRequestAbort,
|
|
2976
|
+
onRequestSimulation,
|
|
2977
|
+
onSetContactPhone
|
|
2978
|
+
};
|
|
2267
2979
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2268
2980
|
ref: dialogRef,
|
|
2269
2981
|
className: cls("emergency-panel", !open && "emergency-panel--hidden"),
|
|
@@ -2274,48 +2986,18 @@ function EmergencyPanel(props) {
|
|
|
2274
2986
|
"aria-hidden": !open,
|
|
2275
2987
|
inert: !open,
|
|
2276
2988
|
tabIndex: -1,
|
|
2277
|
-
children: [
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
loading,
|
|
2290
|
-
locale,
|
|
2291
|
-
geolocationError,
|
|
2292
|
-
activationError,
|
|
2293
|
-
error,
|
|
2294
|
-
abortResult,
|
|
2295
|
-
simulationResult,
|
|
2296
|
-
onRefresh,
|
|
2297
|
-
onRetry,
|
|
2298
|
-
onDismissFeedback
|
|
2299
|
-
})
|
|
2300
|
-
}),
|
|
2301
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyFooter, {
|
|
2302
|
-
active,
|
|
2303
|
-
busy,
|
|
2304
|
-
aborting,
|
|
2305
|
-
feedbackVisible,
|
|
2306
|
-
onActivate,
|
|
2307
|
-
onRequestAbort,
|
|
2308
|
-
onRequestSimulation
|
|
2309
|
-
}),
|
|
2310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyConfirmation, {
|
|
2311
|
-
abortConfirmation,
|
|
2312
|
-
simulationConfirmation,
|
|
2313
|
-
onCancelAbort,
|
|
2314
|
-
onCancelSimulation,
|
|
2315
|
-
onConfirmAbort,
|
|
2316
|
-
onConfirmSimulation
|
|
2317
|
-
})
|
|
2318
|
-
]
|
|
2989
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyScreenProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActiveScreen, {
|
|
2990
|
+
screenProps,
|
|
2991
|
+
open,
|
|
2992
|
+
forcePrimary
|
|
2993
|
+
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmergencyConfirmation, {
|
|
2994
|
+
abortConfirmation,
|
|
2995
|
+
simulationConfirmation,
|
|
2996
|
+
onCancelAbort,
|
|
2997
|
+
onCancelSimulation,
|
|
2998
|
+
onConfirmAbort,
|
|
2999
|
+
onConfirmSimulation
|
|
3000
|
+
})]
|
|
2319
3001
|
});
|
|
2320
3002
|
}
|
|
2321
3003
|
|
|
@@ -2399,6 +3081,7 @@ function EmergencyRoot() {
|
|
|
2399
3081
|
const responders = useEmergencyStore((state) => state.responders);
|
|
2400
3082
|
const resumeAvailable = useEmergencyStore((state) => state.resumeAvailable);
|
|
2401
3083
|
const geolocationError = useEmergencyStore((state) => state.geolocationError);
|
|
3084
|
+
const contactPhone = useEmergencyStore((state) => state.contactPhone);
|
|
2402
3085
|
const lastError = useEmergencyStore((state) => state.lastError);
|
|
2403
3086
|
const abortResult = useEmergencyStore((state) => state.abortResult);
|
|
2404
3087
|
const simulationResult = useEmergencyStore((state) => state.simulationResult);
|
|
@@ -2424,6 +3107,7 @@ function EmergencyRoot() {
|
|
|
2424
3107
|
responders,
|
|
2425
3108
|
refreshing: phase.kind === "refreshing",
|
|
2426
3109
|
geolocationError,
|
|
3110
|
+
contactPhone,
|
|
2427
3111
|
activationError,
|
|
2428
3112
|
error: showError ? error : null,
|
|
2429
3113
|
abortResult,
|
|
@@ -2450,7 +3134,8 @@ function EmergencyRoot() {
|
|
|
2450
3134
|
},
|
|
2451
3135
|
onConfirmSimulation: () => {
|
|
2452
3136
|
client.simulate();
|
|
2453
|
-
}
|
|
3137
|
+
},
|
|
3138
|
+
onSetContactPhone: (phone) => client.setContactPhone(phone)
|
|
2454
3139
|
})] });
|
|
2455
3140
|
}
|
|
2456
3141
|
|
|
@@ -2482,6 +3167,7 @@ function createFailedClient(error) {
|
|
|
2482
3167
|
lastError: error,
|
|
2483
3168
|
geolocation: null,
|
|
2484
3169
|
geolocationError: null,
|
|
3170
|
+
contactPhone: null,
|
|
2485
3171
|
realtimeStatus: "idle",
|
|
2486
3172
|
abortResult: null,
|
|
2487
3173
|
simulationResult: null,
|
|
@@ -2510,7 +3196,8 @@ function createFailedClient(error) {
|
|
|
2510
3196
|
cancelAbortConfirmation: noop,
|
|
2511
3197
|
requestSimulationConfirmation: noop,
|
|
2512
3198
|
cancelSimulationConfirmation: noop,
|
|
2513
|
-
dismissFeedback: noop
|
|
3199
|
+
dismissFeedback: noop,
|
|
3200
|
+
setContactPhone: noop
|
|
2514
3201
|
};
|
|
2515
3202
|
}
|
|
2516
3203
|
function attachTrigger(trigger, client) {
|
|
@@ -2599,6 +3286,7 @@ function mount(options) {
|
|
|
2599
3286
|
requestSimulationConfirmation: () => client.requestSimulationConfirmation(),
|
|
2600
3287
|
cancelSimulationConfirmation: () => client.cancelSimulationConfirmation(),
|
|
2601
3288
|
dismissFeedback: () => client.dismissFeedback(),
|
|
3289
|
+
setContactPhone: (phone) => client.setContactPhone(phone),
|
|
2602
3290
|
destroy
|
|
2603
3291
|
};
|
|
2604
3292
|
}
|