@aglyn/plugins-marketing 1.0.0-beta.143

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.
Files changed (183) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +56 -0
  4. package/src/index.d.ts +19 -0
  5. package/src/index.js +20 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/announcement-bar-card.component.d.ts +20 -0
  8. package/src/lib/components/announcement-bar-card.component.js +292 -0
  9. package/src/lib/components/announcement-bar-card.component.js.map +1 -0
  10. package/src/lib/components/campaign-composer.d.ts +84 -0
  11. package/src/lib/components/campaign-composer.js +1643 -0
  12. package/src/lib/components/campaign-composer.js.map +1 -0
  13. package/src/lib/components/campaign-conversions-card.d.ts +22 -0
  14. package/src/lib/components/campaign-conversions-card.js +642 -0
  15. package/src/lib/components/campaign-conversions-card.js.map +1 -0
  16. package/src/lib/components/campaign-detail-card.d.ts +55 -0
  17. package/src/lib/components/campaign-detail-card.js +771 -0
  18. package/src/lib/components/campaign-detail-card.js.map +1 -0
  19. package/src/lib/components/campaign-edit-drawer.d.ts +60 -0
  20. package/src/lib/components/campaign-edit-drawer.js +252 -0
  21. package/src/lib/components/campaign-edit-drawer.js.map +1 -0
  22. package/src/lib/components/campaign-email-zones.d.ts +111 -0
  23. package/src/lib/components/campaign-email-zones.js +54 -0
  24. package/src/lib/components/campaign-email-zones.js.map +1 -0
  25. package/src/lib/components/campaign-glance-card.component.d.ts +18 -0
  26. package/src/lib/components/campaign-glance-card.component.js +151 -0
  27. package/src/lib/components/campaign-glance-card.component.js.map +1 -0
  28. package/src/lib/components/campaign-members-section.d.ts +87 -0
  29. package/src/lib/components/campaign-members-section.js +499 -0
  30. package/src/lib/components/campaign-members-section.js.map +1 -0
  31. package/src/lib/components/campaign-reach-sections.d.ts +137 -0
  32. package/src/lib/components/campaign-reach-sections.js +694 -0
  33. package/src/lib/components/campaign-reach-sections.js.map +1 -0
  34. package/src/lib/components/campaign-report-card.d.ts +91 -0
  35. package/src/lib/components/campaign-report-card.js +667 -0
  36. package/src/lib/components/campaign-report-card.js.map +1 -0
  37. package/src/lib/components/campaign-test-send-drawer.d.ts +45 -0
  38. package/src/lib/components/campaign-test-send-drawer.js +238 -0
  39. package/src/lib/components/campaign-test-send-drawer.js.map +1 -0
  40. package/src/lib/components/campaigns-card.d.ts +31 -0
  41. package/src/lib/components/campaigns-card.js +667 -0
  42. package/src/lib/components/campaigns-card.js.map +1 -0
  43. package/src/lib/components/conversion-attribution.component.d.ts +62 -0
  44. package/src/lib/components/conversion-attribution.component.js +127 -0
  45. package/src/lib/components/conversion-attribution.component.js.map +1 -0
  46. package/src/lib/components/email-compose-card.d.ts +12 -0
  47. package/src/lib/components/email-compose-card.js +157 -0
  48. package/src/lib/components/email-compose-card.js.map +1 -0
  49. package/src/lib/components/email-detail.d.ts +40 -0
  50. package/src/lib/components/email-detail.js +1180 -0
  51. package/src/lib/components/email-detail.js.map +1 -0
  52. package/src/lib/components/email-edit-drawer.d.ts +54 -0
  53. package/src/lib/components/email-edit-drawer.js +172 -0
  54. package/src/lib/components/email-edit-drawer.js.map +1 -0
  55. package/src/lib/components/email-messages-widget.d.ts +22 -0
  56. package/src/lib/components/email-messages-widget.js +49 -0
  57. package/src/lib/components/email-messages-widget.js.map +1 -0
  58. package/src/lib/components/email-recipients-card.d.ts +50 -0
  59. package/src/lib/components/email-recipients-card.js +338 -0
  60. package/src/lib/components/email-recipients-card.js.map +1 -0
  61. package/src/lib/components/emails-list-card.d.ts +36 -0
  62. package/src/lib/components/emails-list-card.js +544 -0
  63. package/src/lib/components/emails-list-card.js.map +1 -0
  64. package/src/lib/components/experiment-zones.d.ts +78 -0
  65. package/src/lib/components/experiment-zones.js +65 -0
  66. package/src/lib/components/experiment-zones.js.map +1 -0
  67. package/src/lib/components/host-experiments-card.component.d.ts +17 -0
  68. package/src/lib/components/host-experiments-card.component.js +887 -0
  69. package/src/lib/components/host-experiments-card.component.js.map +1 -0
  70. package/src/lib/components/host-marketing-summary-card.component.d.ts +15 -0
  71. package/src/lib/components/host-marketing-summary-card.component.js +161 -0
  72. package/src/lib/components/host-marketing-summary-card.component.js.map +1 -0
  73. package/src/lib/components/host-overlays-card.component.d.ts +19 -0
  74. package/src/lib/components/host-overlays-card.component.js +783 -0
  75. package/src/lib/components/host-overlays-card.component.js.map +1 -0
  76. package/src/lib/components/marketing-console-page.d.ts +28 -0
  77. package/src/lib/components/marketing-console-page.js +166 -0
  78. package/src/lib/components/marketing-console-page.js.map +1 -0
  79. package/src/lib/components/marketing-console-sections.d.ts +34 -0
  80. package/src/lib/components/marketing-console-sections.js +77 -0
  81. package/src/lib/components/marketing-console-sections.js.map +1 -0
  82. package/src/lib/components/overlay-stats-row.component.d.ts +15 -0
  83. package/src/lib/components/overlay-stats-row.component.js +78 -0
  84. package/src/lib/components/overlay-stats-row.component.js.map +1 -0
  85. package/src/lib/components/popup-card.component.d.ts +18 -0
  86. package/src/lib/components/popup-card.component.js +462 -0
  87. package/src/lib/components/popup-card.component.js.map +1 -0
  88. package/src/lib/components/record-attribution-widget.d.ts +35 -0
  89. package/src/lib/components/record-attribution-widget.js +33 -0
  90. package/src/lib/components/record-attribution-widget.js.map +1 -0
  91. package/src/lib/components/site-runtime.d.ts +9 -0
  92. package/src/lib/components/site-runtime.js +1081 -0
  93. package/src/lib/components/site-runtime.js.map +1 -0
  94. package/src/lib/components/use-campaign-send-api.d.ts +35 -0
  95. package/src/lib/components/use-campaign-send-api.js +99 -0
  96. package/src/lib/components/use-campaign-send-api.js.map +1 -0
  97. package/src/lib/components/use-campaign-topic-options.d.ts +20 -0
  98. package/src/lib/components/use-campaign-topic-options.js +44 -0
  99. package/src/lib/components/use-campaign-topic-options.js.map +1 -0
  100. package/src/lib/components/use-emails-hub-path.d.ts +39 -0
  101. package/src/lib/components/use-emails-hub-path.js +70 -0
  102. package/src/lib/components/use-emails-hub-path.js.map +1 -0
  103. package/src/lib/components/use-marketing-hub-path.d.ts +21 -0
  104. package/src/lib/components/use-marketing-hub-path.js +50 -0
  105. package/src/lib/components/use-marketing-hub-path.js.map +1 -0
  106. package/src/lib/components/use-overlay-copy-editor.d.ts +79 -0
  107. package/src/lib/components/use-overlay-copy-editor.js +110 -0
  108. package/src/lib/components/use-overlay-copy-editor.js.map +1 -0
  109. package/src/lib/constants/bundle-common.d.ts +8 -0
  110. package/src/lib/constants/bundle-common.js +9 -0
  111. package/src/lib/constants/bundle-common.js.map +1 -0
  112. package/src/lib/model/campaign-membership-figures.d.ts +109 -0
  113. package/src/lib/model/campaign-membership-figures.js +113 -0
  114. package/src/lib/model/campaign-membership-figures.js.map +1 -0
  115. package/src/lib/model/compile-client-automations.d.ts +65 -0
  116. package/src/lib/model/compile-client-automations.js +95 -0
  117. package/src/lib/model/compile-client-automations.js.map +1 -0
  118. package/src/lib/model/experiments.d.ts +130 -0
  119. package/src/lib/model/experiments.js +186 -0
  120. package/src/lib/model/experiments.js.map +1 -0
  121. package/src/lib/model/index.d.ts +26 -0
  122. package/src/lib/model/index.js +26 -0
  123. package/src/lib/model/index.js.map +1 -0
  124. package/src/lib/model/marketing-record-routes.d.ts +6 -0
  125. package/src/lib/model/marketing-record-routes.js +46 -0
  126. package/src/lib/model/marketing-record-routes.js.map +1 -0
  127. package/src/lib/model/overlay-copy.d.ts +62 -0
  128. package/src/lib/model/overlay-copy.js +78 -0
  129. package/src/lib/model/overlay-copy.js.map +1 -0
  130. package/src/lib/model/overlays.d.ts +113 -0
  131. package/src/lib/model/overlays.js +93 -0
  132. package/src/lib/model/overlays.js.map +1 -0
  133. package/src/lib/model/site-contract.d.ts +100 -0
  134. package/src/lib/model/site-contract.js +23 -0
  135. package/src/lib/model/site-contract.js.map +1 -0
  136. package/src/lib/plugin.d.ts +27 -0
  137. package/src/lib/plugin.js +168 -0
  138. package/src/lib/plugin.js.map +1 -0
  139. package/src/lib/preview-props.d.ts +31 -0
  140. package/src/lib/preview-props.js +54 -0
  141. package/src/lib/preview-props.js.map +1 -0
  142. package/src/lib/server/campaign-manage.d.ts +62 -0
  143. package/src/lib/server/campaign-manage.js +829 -0
  144. package/src/lib/server/campaign-manage.js.map +1 -0
  145. package/src/lib/server/campaign-process-scheduled.d.ts +26 -0
  146. package/src/lib/server/campaign-process-scheduled.js +198 -0
  147. package/src/lib/server/campaign-process-scheduled.js.map +1 -0
  148. package/src/lib/server/campaign-recipients.d.ts +55 -0
  149. package/src/lib/server/campaign-recipients.js +219 -0
  150. package/src/lib/server/campaign-recipients.js.map +1 -0
  151. package/src/lib/server/campaign-send.d.ts +487 -0
  152. package/src/lib/server/campaign-send.js +3157 -0
  153. package/src/lib/server/campaign-send.js.map +1 -0
  154. package/src/lib/server/email-campaign-reach.d.ts +174 -0
  155. package/src/lib/server/email-campaign-reach.js +254 -0
  156. package/src/lib/server/email-campaign-reach.js.map +1 -0
  157. package/src/lib/server/email-events.d.ts +27 -0
  158. package/src/lib/server/email-events.js +714 -0
  159. package/src/lib/server/email-events.js.map +1 -0
  160. package/src/lib/server/get-client-automations.d.ts +60 -0
  161. package/src/lib/server/get-client-automations.js +87 -0
  162. package/src/lib/server/get-client-automations.js.map +1 -0
  163. package/src/lib/server/get-overlays.d.ts +28 -0
  164. package/src/lib/server/get-overlays.js +65 -0
  165. package/src/lib/server/get-overlays.js.map +1 -0
  166. package/src/lib/server/get-screen-experiments.d.ts +42 -0
  167. package/src/lib/server/get-screen-experiments.js +82 -0
  168. package/src/lib/server/get-screen-experiments.js.map +1 -0
  169. package/src/lib/server/lists-materialize.d.ts +18 -0
  170. package/src/lib/server/lists-materialize.js +130 -0
  171. package/src/lib/server/lists-materialize.js.map +1 -0
  172. package/src/lib/server/marketing-figures.d.ts +37 -0
  173. package/src/lib/server/marketing-figures.js +248 -0
  174. package/src/lib/server/marketing-figures.js.map +1 -0
  175. package/src/lib/server/site-page-enricher.d.ts +26 -0
  176. package/src/lib/server/site-page-enricher.js +210 -0
  177. package/src/lib/server/site-page-enricher.js.map +1 -0
  178. package/src/lib/server.d.ts +20 -0
  179. package/src/lib/server.js +152 -0
  180. package/src/lib/server.js.map +1 -0
  181. package/src/lib/site.d.ts +22 -0
  182. package/src/lib/site.js +48 -0
  183. package/src/lib/site.js.map +1 -0
@@ -0,0 +1,783 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
19
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
20
+ import { checkEntitlement, createResourceUid, pluginDocsHelp } from "@aglyn/aglyn";
21
+ import { overlayActiveAt } from "../model/index.js";
22
+ import { mdiChevronDown, mdiChevronUp } from "@aglyn/shared-data-mdi";
23
+ import { CardDisplay, MdiIcon, useConfirmationContext } from "@aglyn/shared-ui-jsx";
24
+ import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
25
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
26
+ import { Timestamp } from "@aglyn/shared-util-timestamp";
27
+ import { Alert, Button, Chip, IconButton, Dialog, DialogActions, DialogContent, DialogTitle, MenuItem, Stack, Switch, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from "@mui/material";
28
+ import { collection, deleteDoc, doc, limit, orderBy, query, setDoc } from "firebase/firestore";
29
+ import { useState } from "react";
30
+ import { useFirestore, useFirestoreCollection, useHostActivityLogger, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
31
+ import { OVERLAY_COPY_HELPER_TEXT, shownAsTypedHelperText, useOverlayCopyEditor } from "./use-overlay-copy-editor.js";
32
+ /**
33
+ * How many overlays the card reads.
34
+ *
35
+ * A ceiling rather than a page size — see the query, which explains why this
36
+ * one list is deliberately not paginated. Generous on purpose: a site runs a
37
+ * handful of banners and popups, and the number exists to bound a pathological
38
+ * collection rather than to bound a normal one.
39
+ */ const CEILING = 50;
40
+ const EMPTY_BAR = {
41
+ kind: 'bar',
42
+ enabled: true,
43
+ bar: {
44
+ dismissible: true
45
+ }
46
+ };
47
+ const EMPTY_POPUP = {
48
+ kind: 'popup',
49
+ enabled: true,
50
+ popup: {
51
+ trigger: 'delay',
52
+ triggerValue: 3,
53
+ frequencyDays: 7
54
+ }
55
+ };
56
+ function toDatetimeLocal(ms) {
57
+ if (!ms) return '';
58
+ const date = new Date(ms);
59
+ const pad = (value)=>String(value).padStart(2, '0');
60
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-` + `${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
61
+ }
62
+ function fromDatetimeLocal(value) {
63
+ if (!value) return undefined;
64
+ const ms = new Date(value).getTime();
65
+ return Number.isFinite(ms) ? ms : undefined;
66
+ }
67
+ function parsePatterns(value) {
68
+ return value.split(',').map((pattern)=>pattern.trim()).filter(Boolean);
69
+ }
70
+ /**
71
+ * Marketing hub overlays manager (AGL-251): multiple announcement bars
72
+ * and popups at `hosts/{hostId}/overlays`, each with a schedule window
73
+ * and page targeting; the tenant render shows the first active match per
74
+ * kind (overlay docs win over the legacy single bar/popup fields). A bar's
75
+ * text and a popup's headline and body are edited through
76
+ * `useOverlayCopyEditor`, like the single bar and popup cards (AGL-2885).
77
+ */ export function HostOverlaysCard(props) {
78
+ var _ref, _editor_name, _shownAsTypedHelperText, _ref1, _ref2, _ref3, _shownAsTypedHelperText1, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _editor_pathPatterns, _editor_excludePathPatterns;
79
+ var _editor_bar, _editor_popup, _editor_popup1, _editor_bar1, _editor_popup2, _editor_popup3, _editor_bar2, _editor_bar3, _editor_bar4, _editor_bar5, _editor_popup4, _editor_popup5, _editor_popup6, _editor_popup7, _editor_popup8, _editor_popup9, _editor_popup10, _editor_popup11, _editor_popup12, _editor_popup13, _editor_bar6, _editor_popup14, _editor_popup15;
80
+ const { hostId } = props;
81
+ const firestore = useFirestore();
82
+ const { org } = props;
83
+ const { enqueueSnackbar } = useSnackbar();
84
+ const { confirm } = useConfirmationContext();
85
+ const logActivity = useHostActivityLogger(hostId);
86
+ const entitled = checkEntitlement(org, 'marketingOverlays');
87
+ const { data: overlayDocs, status: overlaysStatus, /**
88
+ * The overlay rows the editor is seeded from are unconfirmed by the
89
+ * server (AGL-1358). Editing one spreads the whole stored row into
90
+ * `editor` and writes it back with NO options argument at all — a full
91
+ * document replace — so a cached seed reverts every field nobody
92
+ * touched. Including `stats`, the lifetime impression/click/dismissal
93
+ * counters the org beacon increments: a save here would roll live
94
+ * engagement numbers back to whenever the snapshot was taken.
95
+ */ fromCache: overlaysFromCache } = useFirestoreCollection(()=>query(collection(firestore, 'hosts', hostId, 'overlays'), /*
96
+ * ORDERED AND CEILINGED, deliberately not paged (AGL-2501).
97
+ *
98
+ * ## Why the read is ordered
99
+ *
100
+ * `limit(50)` alone is answered in DOCUMENT-ID order over ids from
101
+ * `createResourceUid()`, so the window was a pseudo-random fifty that
102
+ * the client sort below arranged into a believable precedence list.
103
+ * `name` is the one field every overlay carries: `handleSave` writes
104
+ * `name: (…).trim() || null` on every save, and it is the only writer
105
+ * that CREATES one — the analytics beacon uses `update()` precisely so
106
+ * a stale page cannot mint a stats-only stray, and `overlays` is not
107
+ * in `IMPORTABLE_FIELDS`, so no restore path makes one either. A null
108
+ * name still matches an `orderBy`; an ABSENT field would not.
109
+ *
110
+ * ## Why this list is not paged
111
+ *
112
+ * The row order IS the feature: the first enabled overlay of each kind
113
+ * is the one a visitor sees (AGL-270), and the arrows reorder by
114
+ * swapping `order` with the ADJACENT row. A page boundary separates a
115
+ * row from the neighbor it would swap with, so the eleventh overlay
116
+ * could never be moved into tenth place — the same reason the console's
117
+ * screen tree and starter bundles are ceilinged rather than paged.
118
+ *
119
+ * `orderBy('order')` is not an option either, and that is what makes
120
+ * the precedence sort a client-side one: `EMPTY_BAR` and `EMPTY_POPUP`
121
+ * carry no `order`, and only `handleMove` ever writes one, so ordering
122
+ * the query on it would hide every overlay nobody has reordered rather
123
+ * than mis-sorting it. The client sort holds the WHOLE window, which is
124
+ * what makes sorting it here honest.
125
+ */ orderBy('name'), // One past the ceiling, so "there are more overlays than these" is a
126
+ // fact rather than a guess from `length === 50`.
127
+ limit(CEILING + 1)), [
128
+ firestore,
129
+ hostId
130
+ ], {
131
+ idField: '$id'
132
+ });
133
+ const truncated = ((_ref = overlayDocs == null ? void 0 : overlayDocs.length) != null ? _ref : 0) > CEILING;
134
+ const overlays = [
135
+ ...overlayDocs != null ? overlayDocs : []
136
+ ].slice(0, CEILING).sort((a, b)=>{
137
+ var _a_order, _b_order, _a_name, _b_name;
138
+ return ((_a_order = a.order) != null ? _a_order : 0) - ((_b_order = b.order) != null ? _b_order : 0) || String((_a_name = a.name) != null ? _a_name : '').localeCompare(String((_b_name = b.name) != null ? _b_name : ''));
139
+ });
140
+ const [editor, setEditor] = useState(null);
141
+ // The editor's copy is held in its stored form; the fields show it as typed.
142
+ const copy = useOverlayCopyEditor({
143
+ hostId,
144
+ usesTokens: entitled && [
145
+ editor == null ? void 0 : (_editor_bar = editor.bar) == null ? void 0 : _editor_bar.text,
146
+ editor == null ? void 0 : (_editor_popup = editor.popup) == null ? void 0 : _editor_popup.headline,
147
+ editor == null ? void 0 : (_editor_popup1 = editor.popup) == null ? void 0 : _editor_popup1.body
148
+ ].some((text)=>text == null ? void 0 : text.includes('{{'))
149
+ });
150
+ const barTextShownAsTyped = copy.shownAsTyped(editor == null ? void 0 : (_editor_bar1 = editor.bar) == null ? void 0 : _editor_bar1.text);
151
+ const headlineShownAsTyped = copy.shownAsTyped(editor == null ? void 0 : (_editor_popup2 = editor.popup) == null ? void 0 : _editor_popup2.headline);
152
+ const bodyShownAsTyped = copy.shownAsTyped(editor == null ? void 0 : (_editor_popup3 = editor.popup) == null ? void 0 : _editor_popup3.body);
153
+ const patch = (partial)=>setEditor((previous)=>previous ? _extends({}, previous, partial) : previous);
154
+ const patchBar = (partial)=>setEditor((previous)=>{
155
+ var _previous_bar;
156
+ return previous ? _extends({}, previous, {
157
+ bar: _extends({}, (_previous_bar = previous.bar) != null ? _previous_bar : {}, partial)
158
+ }) : previous;
159
+ });
160
+ const patchPopup = (partial)=>setEditor((previous)=>{
161
+ var _previous_popup;
162
+ return previous ? _extends({}, previous, {
163
+ popup: _extends({}, (_previous_popup = previous.popup) != null ? _previous_popup : {}, partial)
164
+ }) : previous;
165
+ });
166
+ const handleSave = async ()=>{
167
+ var _editor_$id;
168
+ var _editor_bar_text, _editor_bar, _editor_popup_body, _editor_popup;
169
+ if (!editor) return;
170
+ if (editor.kind === 'bar' && !((_editor_bar = editor.bar) == null ? void 0 : (_editor_bar_text = _editor_bar.text) == null ? void 0 : _editor_bar_text.trim())) {
171
+ return void enqueueSnackbar('Enter the bar text', {
172
+ variant: 'warning',
173
+ persist: false
174
+ });
175
+ }
176
+ if (editor.kind === 'popup' && !((_editor_popup = editor.popup) == null ? void 0 : (_editor_popup_body = _editor_popup.body) == null ? void 0 : _editor_popup_body.trim())) {
177
+ return void enqueueSnackbar('Enter the popup body', {
178
+ variant: 'warning',
179
+ persist: false
180
+ });
181
+ }
182
+ const id = (_editor_$id = editor.$id) != null ? _editor_$id : createResourceUid();
183
+ const { $id: _ignored, createdAt: _createdAt, updatedAt: _updatedAt } = editor, payload = _object_without_properties_loose(editor, [
184
+ "$id",
185
+ "createdAt",
186
+ "updatedAt"
187
+ ]);
188
+ try {
189
+ var _editor_name;
190
+ // JSON round-trip strips undefined values Firestore rejects. The copy
191
+ // is stored again here, for a name typed before the variables arrived.
192
+ const cleaned = JSON.parse(JSON.stringify(_extends({}, payload, payload.bar ? {
193
+ bar: _extends({}, payload.bar, {
194
+ text: copy.stored(payload.bar.text)
195
+ })
196
+ } : {}, payload.popup ? {
197
+ popup: _extends({}, payload.popup, {
198
+ headline: copy.stored(payload.popup.headline),
199
+ body: copy.stored(payload.popup.body)
200
+ })
201
+ } : {}, {
202
+ name: ((_editor_name = editor.name) != null ? _editor_name : '').trim() || null
203
+ })));
204
+ /**
205
+ * Refuse an EDIT whose seed the server never confirmed (AGL-1358).
206
+ *
207
+ * This write has no options argument, so it is a full document replace
208
+ * of a payload copied wholesale off the listener — `merge` would not
209
+ * have helped anyway, since every field is present. The activity log
210
+ * is inside the guard too: a logged "Updated overlay" whose write never
211
+ * happened is worse than neither, because the history then disagrees
212
+ * with the overlay it claims to explain.
213
+ *
214
+ * Only the edit path. A NEW overlay starts from `EMPTY_BAR`/
215
+ * `EMPTY_POPUP` at a fresh uid and can overwrite nothing, and the first
216
+ * snapshot of any listener is `fromCache: true`, so guarding a create
217
+ * would refuse a save that was never unsafe.
218
+ *
219
+ * The guard WRAPS the write: an early return is a shape you can keep
220
+ * while losing the protection.
221
+ */ const verdict = await writeGuardedBySeed({
222
+ subject: 'overlay',
223
+ unreadable: Boolean(editor.$id) && overlaysStatus === 'error',
224
+ fromCache: Boolean(editor.$id) && overlaysFromCache
225
+ }, async ()=>{
226
+ await setDoc(doc(firestore, 'hosts', hostId, 'overlays', id), _extends({}, cleaned, {
227
+ updatedAt: Timestamp.now()
228
+ }, editor.$id ? {} : {
229
+ createdAt: Timestamp.now()
230
+ }));
231
+ logActivity(editor.$id ? 'Updated overlay' : 'Created overlay', _extends({
232
+ type: 'content',
233
+ id
234
+ }, editor.name ? {
235
+ name: editor.name
236
+ } : {}));
237
+ });
238
+ // A refusal keeps the editor open with everything that was typed.
239
+ if (!verdict.ok) {
240
+ return void enqueueSnackbar(verdict.message, {
241
+ variant: 'warning',
242
+ persist: false
243
+ });
244
+ }
245
+ enqueueSnackbar('Overlay saved', {
246
+ variant: 'success',
247
+ persist: false
248
+ });
249
+ setEditor(null);
250
+ } catch (error) {
251
+ console.error(error);
252
+ enqueueSnackbar('An error has occurred', {
253
+ variant: 'error'
254
+ });
255
+ }
256
+ };
257
+ const handleDelete = async (overlay)=>{
258
+ var _overlay_name;
259
+ if (!overlay.$id) return;
260
+ const confirmed = await confirm({
261
+ title: 'Delete overlay?',
262
+ description: `"${(_overlay_name = overlay.name) != null ? _overlay_name : overlay.$id}" stops showing immediately.`,
263
+ confirmationText: 'Delete',
264
+ confirmationButtonProps: {
265
+ color: 'error'
266
+ }
267
+ })// Resolves with no value and rejects on cancel — gating on the
268
+ // resolved value alone made this always return (AGL-950).
269
+ .then(()=>true).catch(()=>false);
270
+ if (!confirmed) return;
271
+ await deleteDoc(doc(firestore, 'hosts', hostId, 'overlays', overlay.$id));
272
+ enqueueSnackbar('Overlay deleted', {
273
+ variant: 'success',
274
+ persist: false
275
+ });
276
+ logActivity('Deleted overlay', _extends({
277
+ type: 'content',
278
+ id: overlay.$id
279
+ }, overlay.name ? {
280
+ name: overlay.name
281
+ } : {}));
282
+ };
283
+ // Ordering (AGL-270): the first active overlay per kind wins, so the
284
+ // list order is meaningful — swap `order` with the neighbor.
285
+ const handleMove = async (index, direction)=>{
286
+ var _current_order, _neighbor_order;
287
+ const neighbor = overlays[index + direction];
288
+ const current = overlays[index];
289
+ if (!(neighbor == null ? void 0 : neighbor.$id) || !(current == null ? void 0 : current.$id)) return;
290
+ const currentOrder = (_current_order = current.order) != null ? _current_order : index;
291
+ const neighborOrder = (_neighbor_order = neighbor.order) != null ? _neighbor_order : index + direction;
292
+ await Promise.all([
293
+ setDoc(doc(firestore, 'hosts', hostId, 'overlays', current.$id), {
294
+ order: neighborOrder === currentOrder ? neighborOrder + direction : neighborOrder
295
+ }, {
296
+ merge: true
297
+ }),
298
+ setDoc(doc(firestore, 'hosts', hostId, 'overlays', neighbor.$id), {
299
+ order: currentOrder
300
+ }, {
301
+ merge: true
302
+ })
303
+ ]).catch(console.error);
304
+ };
305
+ const handleToggle = async (overlay)=>{
306
+ if (!overlay.$id) return;
307
+ await setDoc(doc(firestore, 'hosts', hostId, 'overlays', overlay.$id), {
308
+ enabled: overlay.enabled === false
309
+ }, {
310
+ merge: true
311
+ });
312
+ };
313
+ // Engagement (AGL-271): lifetime counters the org beacon increments.
314
+ const statsLabel = (overlay)=>{
315
+ var _overlay_stats, _stats_impressions, _stats_clicks, _stats_dismissals;
316
+ const stats = (_overlay_stats = overlay.stats) != null ? _overlay_stats : {};
317
+ const impressions = (_stats_impressions = stats.impressions) != null ? _stats_impressions : 0;
318
+ const clicks = (_stats_clicks = stats.clicks) != null ? _stats_clicks : 0;
319
+ const dismissals = (_stats_dismissals = stats.dismissals) != null ? _stats_dismissals : 0;
320
+ if (!impressions && !clicks && !dismissals) return '—';
321
+ const parts = [
322
+ `${impressions.toLocaleString()} views`
323
+ ];
324
+ if (clicks) parts.push(`${clicks.toLocaleString()} clicks`);
325
+ if (dismissals) parts.push(`${dismissals.toLocaleString()} dismissed`);
326
+ return parts.join(' · ');
327
+ };
328
+ const statusChip = (overlay)=>{
329
+ if (overlay.enabled === false) {
330
+ return /*#__PURE__*/ _jsx(Chip, {
331
+ size: "small",
332
+ label: "Off"
333
+ });
334
+ }
335
+ if (!overlayActiveAt(overlay, Date.now())) {
336
+ return /*#__PURE__*/ _jsx(Chip, {
337
+ size: "small",
338
+ color: "info",
339
+ label: "Scheduled"
340
+ });
341
+ }
342
+ return /*#__PURE__*/ _jsx(Chip, {
343
+ size: "small",
344
+ color: "success",
345
+ label: "Live"
346
+ });
347
+ };
348
+ return /*#__PURE__*/ _jsxs(CardDisplay, {
349
+ header: "Announcement bars & popups",
350
+ help: pluginDocsHelp('marketingOverlays', {
351
+ anchor: '#frequency',
352
+ excerpt: 'Every bar and popup on this site, with its schedule, page ' + 'targeting, and how often a visitor sees it again.'
353
+ }),
354
+ contentGutterX: true,
355
+ contentGutterY: true,
356
+ contentBordered: "all",
357
+ children: [
358
+ !entitled ? /*#__PURE__*/ _jsx(Alert, {
359
+ severity: "info",
360
+ children: 'Announcement bars and popups are included from the Starter ' + 'plan — see Billing to upgrade.'
361
+ }) : /*#__PURE__*/ _jsxs(Stack, {
362
+ spacing: 2,
363
+ children: [
364
+ /*#__PURE__*/ _jsx(Typography, {
365
+ variant: "body2",
366
+ color: "text.secondary",
367
+ children: 'Configure as many bars and popups as you need, each with its ' + 'own schedule and page targeting. When several match a page, ' + 'the first per kind shows.'
368
+ }),
369
+ /*#__PURE__*/ _jsxs(Stack, {
370
+ direction: "row",
371
+ spacing: 1,
372
+ children: [
373
+ /*#__PURE__*/ _jsx(Button, {
374
+ size: "small",
375
+ color: "primary",
376
+ variant: "contained",
377
+ onClick: ()=>setEditor(_extends({}, EMPTY_BAR)),
378
+ children: 'New bar'
379
+ }),
380
+ /*#__PURE__*/ _jsx(Button, {
381
+ size: "small",
382
+ color: "primary",
383
+ variant: "contained",
384
+ onClick: ()=>setEditor(_extends({}, EMPTY_POPUP)),
385
+ children: 'New popup'
386
+ })
387
+ ]
388
+ }),
389
+ truncated ? /*#__PURE__*/ _jsx(Alert, {
390
+ severity: "info",
391
+ children: `Showing ${CEILING} overlays, ordered by name. This site has ` + 'more than that — delete the ones you have finished with, or ' + 'the ones below the ceiling cannot be reordered against them.'
392
+ }) : null,
393
+ overlays.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
394
+ variant: "body2",
395
+ color: "text.secondary",
396
+ children: 'No overlays yet — the single announcement bar and popup ' + 'below keep working as your default surfaces.'
397
+ }) : /*#__PURE__*/ _jsxs(ScrollTable, {
398
+ size: "small",
399
+ children: [
400
+ /*#__PURE__*/ _jsx(TableHead, {
401
+ children: /*#__PURE__*/ _jsxs(TableRow, {
402
+ children: [
403
+ /*#__PURE__*/ _jsx(TableCell, {
404
+ children: 'Name'
405
+ }),
406
+ /*#__PURE__*/ _jsx(TableCell, {
407
+ children: 'Kind'
408
+ }),
409
+ /*#__PURE__*/ _jsx(TableCell, {
410
+ children: 'Status'
411
+ }),
412
+ /*#__PURE__*/ _jsx(TableCell, {
413
+ children: 'Window'
414
+ }),
415
+ /*#__PURE__*/ _jsx(TableCell, {
416
+ children: 'Pages'
417
+ }),
418
+ /*#__PURE__*/ _jsx(TableCell, {
419
+ children: 'Engagement'
420
+ }),
421
+ /*#__PURE__*/ _jsx(TableCell, {
422
+ align: "right",
423
+ children: 'Actions'
424
+ })
425
+ ]
426
+ })
427
+ }),
428
+ /*#__PURE__*/ _jsx(TableBody, {
429
+ children: overlays.map((overlay)=>{
430
+ var _ref, _overlay_name, _ref1, _ref2;
431
+ var _overlay_bar, _overlay_popup, _overlay_pathPatterns;
432
+ return /*#__PURE__*/ _jsxs(TableRow, {
433
+ children: [
434
+ /*#__PURE__*/ _jsx(TableCell, {
435
+ children: (_ref = (_overlay_name = overlay.name) != null ? _overlay_name : overlay.kind === 'bar' ? ((_ref1 = (_overlay_bar = overlay.bar) == null ? void 0 : _overlay_bar.text) != null ? _ref1 : '').slice(0, 32) : ((_ref2 = (_overlay_popup = overlay.popup) == null ? void 0 : _overlay_popup.headline) != null ? _ref2 : '').slice(0, 32)) != null ? _ref : overlay.$id
436
+ }),
437
+ /*#__PURE__*/ _jsx(TableCell, {
438
+ children: overlay.kind === 'bar' ? 'Bar' : 'Popup'
439
+ }),
440
+ /*#__PURE__*/ _jsx(TableCell, {
441
+ children: statusChip(overlay)
442
+ }),
443
+ /*#__PURE__*/ _jsx(TableCell, {
444
+ children: overlay.startAtMs || overlay.endAtMs ? `${overlay.startAtMs ? new Date(overlay.startAtMs).toLocaleDateString() : '…'} → ${overlay.endAtMs ? new Date(overlay.endAtMs).toLocaleDateString() : '…'}` : 'Always'
445
+ }),
446
+ /*#__PURE__*/ _jsx(TableCell, {
447
+ children: ((_overlay_pathPatterns = overlay.pathPatterns) == null ? void 0 : _overlay_pathPatterns.length) ? overlay.pathPatterns.join(', ') : 'All pages'
448
+ }),
449
+ /*#__PURE__*/ _jsx(TableCell, {
450
+ children: /*#__PURE__*/ _jsx(Typography, {
451
+ variant: "caption",
452
+ color: "text.secondary",
453
+ children: statsLabel(overlay)
454
+ })
455
+ }),
456
+ /*#__PURE__*/ _jsxs(TableCell, {
457
+ align: "right",
458
+ children: [
459
+ /*#__PURE__*/ _jsx(IconButton, {
460
+ size: "small",
461
+ "aria-label": "move up",
462
+ disabled: overlays.indexOf(overlay) === 0,
463
+ onClick: ()=>void handleMove(overlays.indexOf(overlay), -1),
464
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
465
+ path: mdiChevronUp.path,
466
+ sx: {
467
+ fontSize: '1rem'
468
+ }
469
+ })
470
+ }),
471
+ /*#__PURE__*/ _jsx(IconButton, {
472
+ size: "small",
473
+ "aria-label": "move down",
474
+ disabled: overlays.indexOf(overlay) === overlays.length - 1,
475
+ onClick: ()=>void handleMove(overlays.indexOf(overlay), 1),
476
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
477
+ path: mdiChevronDown.path,
478
+ sx: {
479
+ fontSize: '1rem'
480
+ }
481
+ })
482
+ }),
483
+ /*#__PURE__*/ _jsx(Switch, {
484
+ size: "small",
485
+ checked: overlay.enabled !== false,
486
+ onChange: ()=>handleToggle(overlay),
487
+ slotProps: {
488
+ input: {
489
+ 'aria-label': 'Enabled'
490
+ }
491
+ }
492
+ }),
493
+ /*#__PURE__*/ _jsx(Button, {
494
+ size: "small",
495
+ color: "primary",
496
+ onClick: ()=>setEditor(_extends({}, overlay)),
497
+ children: 'Edit'
498
+ }),
499
+ /*#__PURE__*/ _jsx(Button, {
500
+ size: "small",
501
+ color: "error",
502
+ onClick: ()=>handleDelete(overlay),
503
+ children: 'Delete'
504
+ })
505
+ ]
506
+ })
507
+ ]
508
+ }, overlay.$id);
509
+ })
510
+ })
511
+ ]
512
+ })
513
+ ]
514
+ }),
515
+ /*#__PURE__*/ _jsxs(Dialog, {
516
+ open: Boolean(editor),
517
+ onClose: ()=>setEditor(null),
518
+ maxWidth: "sm",
519
+ fullWidth: true,
520
+ children: [
521
+ /*#__PURE__*/ _jsx(DialogTitle, {
522
+ children: (editor == null ? void 0 : editor.$id) ? 'Edit overlay' : (editor == null ? void 0 : editor.kind) === 'bar' ? 'New announcement bar' : 'New popup'
523
+ }),
524
+ /*#__PURE__*/ _jsx(DialogContent, {
525
+ children: editor ? /*#__PURE__*/ _jsxs(Stack, {
526
+ spacing: 2,
527
+ sx: {
528
+ mt: 1
529
+ },
530
+ children: [
531
+ /*#__PURE__*/ _jsx(TextField, {
532
+ size: "small",
533
+ label: "Name",
534
+ value: (_editor_name = editor.name) != null ? _editor_name : '',
535
+ onChange: (event)=>patch({
536
+ name: event.target.value
537
+ }),
538
+ helperText: "Internal label shown in this list"
539
+ }),
540
+ editor.kind === 'bar' ? /*#__PURE__*/ _jsxs(_Fragment, {
541
+ children: [
542
+ /*#__PURE__*/ _jsx(TextField, {
543
+ size: "small",
544
+ label: "Text",
545
+ required: true,
546
+ value: copy.editable((_editor_bar2 = editor.bar) == null ? void 0 : _editor_bar2.text),
547
+ onChange: (event)=>patchBar({
548
+ text: copy.stored(event.target.value)
549
+ }),
550
+ error: barTextShownAsTyped.length > 0,
551
+ helperText: (_shownAsTypedHelperText = shownAsTypedHelperText(barTextShownAsTyped)) != null ? _shownAsTypedHelperText : OVERLAY_COPY_HELPER_TEXT
552
+ }),
553
+ /*#__PURE__*/ _jsx(TextField, {
554
+ size: "small",
555
+ label: "Link (optional)",
556
+ value: (_ref1 = (_editor_bar3 = editor.bar) == null ? void 0 : _editor_bar3.href) != null ? _ref1 : '',
557
+ onChange: (event)=>patchBar({
558
+ href: event.target.value
559
+ })
560
+ }),
561
+ /*#__PURE__*/ _jsxs(Stack, {
562
+ direction: "row",
563
+ spacing: 1,
564
+ children: [
565
+ /*#__PURE__*/ _jsx(TextField, {
566
+ size: "small",
567
+ label: "Background color",
568
+ value: (_ref2 = (_editor_bar4 = editor.bar) == null ? void 0 : _editor_bar4.backgroundColor) != null ? _ref2 : '',
569
+ onChange: (event)=>patchBar({
570
+ backgroundColor: event.target.value
571
+ })
572
+ }),
573
+ /*#__PURE__*/ _jsx(TextField, {
574
+ size: "small",
575
+ label: "Text color",
576
+ value: (_ref3 = (_editor_bar5 = editor.bar) == null ? void 0 : _editor_bar5.textColor) != null ? _ref3 : '',
577
+ onChange: (event)=>patchBar({
578
+ textColor: event.target.value
579
+ })
580
+ })
581
+ ]
582
+ })
583
+ ]
584
+ }) : /*#__PURE__*/ _jsxs(_Fragment, {
585
+ children: [
586
+ /*#__PURE__*/ _jsx(TextField, {
587
+ size: "small",
588
+ label: "Headline",
589
+ value: copy.editable((_editor_popup4 = editor.popup) == null ? void 0 : _editor_popup4.headline),
590
+ onChange: (event)=>patchPopup({
591
+ headline: copy.stored(event.target.value)
592
+ }),
593
+ error: headlineShownAsTyped.length > 0,
594
+ helperText: shownAsTypedHelperText(headlineShownAsTyped)
595
+ }),
596
+ /*#__PURE__*/ _jsx(TextField, {
597
+ size: "small",
598
+ label: "Body",
599
+ required: true,
600
+ multiline: true,
601
+ minRows: 2,
602
+ value: copy.editable((_editor_popup5 = editor.popup) == null ? void 0 : _editor_popup5.body),
603
+ onChange: (event)=>patchPopup({
604
+ body: copy.stored(event.target.value)
605
+ }),
606
+ error: bodyShownAsTyped.length > 0,
607
+ helperText: (_shownAsTypedHelperText1 = shownAsTypedHelperText(bodyShownAsTyped)) != null ? _shownAsTypedHelperText1 : OVERLAY_COPY_HELPER_TEXT
608
+ }),
609
+ /*#__PURE__*/ _jsxs(Stack, {
610
+ direction: "row",
611
+ spacing: 1,
612
+ children: [
613
+ /*#__PURE__*/ _jsx(TextField, {
614
+ size: "small",
615
+ label: "CTA label",
616
+ value: (_ref4 = (_editor_popup6 = editor.popup) == null ? void 0 : _editor_popup6.ctaLabel) != null ? _ref4 : '',
617
+ onChange: (event)=>patchPopup({
618
+ ctaLabel: event.target.value
619
+ })
620
+ }),
621
+ /*#__PURE__*/ _jsx(TextField, {
622
+ size: "small",
623
+ label: "CTA link",
624
+ value: (_ref5 = (_editor_popup7 = editor.popup) == null ? void 0 : _editor_popup7.ctaHref) != null ? _ref5 : '',
625
+ onChange: (event)=>patchPopup({
626
+ ctaHref: event.target.value
627
+ })
628
+ })
629
+ ]
630
+ }),
631
+ /*#__PURE__*/ _jsxs(Stack, {
632
+ direction: "row",
633
+ spacing: 1,
634
+ children: [
635
+ /*#__PURE__*/ _jsxs(TextField, {
636
+ select: true,
637
+ size: "small",
638
+ label: "Trigger",
639
+ sx: {
640
+ minWidth: 140
641
+ },
642
+ value: (_ref6 = (_editor_popup8 = editor.popup) == null ? void 0 : _editor_popup8.trigger) != null ? _ref6 : 'delay',
643
+ onChange: (event)=>patchPopup({
644
+ trigger: event.target.value
645
+ }),
646
+ children: [
647
+ /*#__PURE__*/ _jsx(MenuItem, {
648
+ value: "delay",
649
+ children: 'After a delay'
650
+ }),
651
+ /*#__PURE__*/ _jsx(MenuItem, {
652
+ value: "scroll",
653
+ children: 'On scroll'
654
+ }),
655
+ /*#__PURE__*/ _jsx(MenuItem, {
656
+ value: "exit",
657
+ children: 'On exit intent'
658
+ })
659
+ ]
660
+ }),
661
+ /*#__PURE__*/ _jsx(TextField, {
662
+ size: "small",
663
+ type: "number",
664
+ label: ((_ref7 = (_editor_popup9 = editor.popup) == null ? void 0 : _editor_popup9.trigger) != null ? _ref7 : 'delay') === 'scroll' ? 'Scroll %' : 'Seconds',
665
+ value: (_ref8 = (_editor_popup10 = editor.popup) == null ? void 0 : _editor_popup10.triggerValue) != null ? _ref8 : 3,
666
+ onChange: (event)=>patchPopup({
667
+ triggerValue: Number(event.target.value)
668
+ })
669
+ }),
670
+ /*#__PURE__*/ _jsxs(TextField, {
671
+ select: true,
672
+ size: "small",
673
+ label: "Frequency",
674
+ value: ((_editor_popup11 = editor.popup) == null ? void 0 : _editor_popup11.oncePerSession) ? 'session' : 'days',
675
+ onChange: (event)=>patchPopup({
676
+ oncePerSession: event.target.value === 'session'
677
+ }),
678
+ sx: {
679
+ minWidth: 170
680
+ },
681
+ children: [
682
+ /*#__PURE__*/ _jsx(MenuItem, {
683
+ value: "session",
684
+ children: 'Once per session'
685
+ }),
686
+ /*#__PURE__*/ _jsx(MenuItem, {
687
+ value: "days",
688
+ children: 'Re-show after a while'
689
+ })
690
+ ]
691
+ }),
692
+ ((_editor_popup12 = editor.popup) == null ? void 0 : _editor_popup12.oncePerSession) ? null : /*#__PURE__*/ _jsx(TextField, {
693
+ size: "small",
694
+ type: "number",
695
+ label: "Re-show after (days)",
696
+ value: (_ref9 = (_editor_popup13 = editor.popup) == null ? void 0 : _editor_popup13.frequencyDays) != null ? _ref9 : 7,
697
+ onChange: (event)=>patchPopup({
698
+ frequencyDays: Number(event.target.value)
699
+ })
700
+ })
701
+ ]
702
+ })
703
+ ]
704
+ }),
705
+ /*#__PURE__*/ _jsxs(Stack, {
706
+ direction: "row",
707
+ spacing: 1,
708
+ children: [
709
+ /*#__PURE__*/ _jsx(TextField, {
710
+ size: "small",
711
+ type: "datetime-local",
712
+ label: "Show from",
713
+ slotProps: {
714
+ inputLabel: {
715
+ shrink: true
716
+ }
717
+ },
718
+ value: toDatetimeLocal(editor.startAtMs),
719
+ onChange: (event)=>patch({
720
+ startAtMs: fromDatetimeLocal(event.target.value)
721
+ })
722
+ }),
723
+ /*#__PURE__*/ _jsx(TextField, {
724
+ size: "small",
725
+ type: "datetime-local",
726
+ label: "Show until",
727
+ slotProps: {
728
+ inputLabel: {
729
+ shrink: true
730
+ }
731
+ },
732
+ value: toDatetimeLocal(editor.endAtMs),
733
+ onChange: (event)=>patch({
734
+ endAtMs: fromDatetimeLocal(event.target.value)
735
+ })
736
+ })
737
+ ]
738
+ }),
739
+ /*#__PURE__*/ _jsx(TextField, {
740
+ size: "small",
741
+ label: "Show on pages",
742
+ value: ((_editor_pathPatterns = editor.pathPatterns) != null ? _editor_pathPatterns : []).join(', '),
743
+ onChange: (event)=>patch({
744
+ pathPatterns: parsePatterns(event.target.value)
745
+ }),
746
+ helperText: 'Comma-separated paths; /blog/* matches a section. ' + 'Empty = every page.'
747
+ }),
748
+ /*#__PURE__*/ _jsx(TextField, {
749
+ size: "small",
750
+ label: "Never show on",
751
+ value: ((_editor_excludePathPatterns = editor.excludePathPatterns) != null ? _editor_excludePathPatterns : []).join(', '),
752
+ onChange: (event)=>patch({
753
+ excludePathPatterns: parsePatterns(event.target.value)
754
+ })
755
+ })
756
+ ]
757
+ }) : null
758
+ }),
759
+ /*#__PURE__*/ _jsxs(DialogActions, {
760
+ children: [
761
+ /*#__PURE__*/ _jsx(Button, {
762
+ color: "inherit",
763
+ onClick: ()=>setEditor(null),
764
+ children: 'Cancel'
765
+ }),
766
+ /*#__PURE__*/ _jsx(Button, {
767
+ variant: "contained",
768
+ color: "primary",
769
+ onClick: handleSave,
770
+ disabled: copy.pending(editor == null ? void 0 : (_editor_bar6 = editor.bar) == null ? void 0 : _editor_bar6.text, editor == null ? void 0 : (_editor_popup14 = editor.popup) == null ? void 0 : _editor_popup14.headline, editor == null ? void 0 : (_editor_popup15 = editor.popup) == null ? void 0 : _editor_popup15.body),
771
+ children: 'Save'
772
+ })
773
+ ]
774
+ })
775
+ ]
776
+ })
777
+ ]
778
+ });
779
+ }
780
+ HostOverlaysCard.displayName = 'HostOverlaysCard';
781
+ export default HostOverlaysCard;
782
+
783
+ //# sourceMappingURL=host-overlays-card.component.js.map