@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.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +56 -0
- package/src/index.d.ts +19 -0
- package/src/index.js +20 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/announcement-bar-card.component.d.ts +20 -0
- package/src/lib/components/announcement-bar-card.component.js +292 -0
- package/src/lib/components/announcement-bar-card.component.js.map +1 -0
- package/src/lib/components/campaign-composer.d.ts +84 -0
- package/src/lib/components/campaign-composer.js +1643 -0
- package/src/lib/components/campaign-composer.js.map +1 -0
- package/src/lib/components/campaign-conversions-card.d.ts +22 -0
- package/src/lib/components/campaign-conversions-card.js +642 -0
- package/src/lib/components/campaign-conversions-card.js.map +1 -0
- package/src/lib/components/campaign-detail-card.d.ts +55 -0
- package/src/lib/components/campaign-detail-card.js +771 -0
- package/src/lib/components/campaign-detail-card.js.map +1 -0
- package/src/lib/components/campaign-edit-drawer.d.ts +60 -0
- package/src/lib/components/campaign-edit-drawer.js +252 -0
- package/src/lib/components/campaign-edit-drawer.js.map +1 -0
- package/src/lib/components/campaign-email-zones.d.ts +111 -0
- package/src/lib/components/campaign-email-zones.js +54 -0
- package/src/lib/components/campaign-email-zones.js.map +1 -0
- package/src/lib/components/campaign-glance-card.component.d.ts +18 -0
- package/src/lib/components/campaign-glance-card.component.js +151 -0
- package/src/lib/components/campaign-glance-card.component.js.map +1 -0
- package/src/lib/components/campaign-members-section.d.ts +87 -0
- package/src/lib/components/campaign-members-section.js +499 -0
- package/src/lib/components/campaign-members-section.js.map +1 -0
- package/src/lib/components/campaign-reach-sections.d.ts +137 -0
- package/src/lib/components/campaign-reach-sections.js +694 -0
- package/src/lib/components/campaign-reach-sections.js.map +1 -0
- package/src/lib/components/campaign-report-card.d.ts +91 -0
- package/src/lib/components/campaign-report-card.js +667 -0
- package/src/lib/components/campaign-report-card.js.map +1 -0
- package/src/lib/components/campaign-test-send-drawer.d.ts +45 -0
- package/src/lib/components/campaign-test-send-drawer.js +238 -0
- package/src/lib/components/campaign-test-send-drawer.js.map +1 -0
- package/src/lib/components/campaigns-card.d.ts +31 -0
- package/src/lib/components/campaigns-card.js +667 -0
- package/src/lib/components/campaigns-card.js.map +1 -0
- package/src/lib/components/conversion-attribution.component.d.ts +62 -0
- package/src/lib/components/conversion-attribution.component.js +127 -0
- package/src/lib/components/conversion-attribution.component.js.map +1 -0
- package/src/lib/components/email-compose-card.d.ts +12 -0
- package/src/lib/components/email-compose-card.js +157 -0
- package/src/lib/components/email-compose-card.js.map +1 -0
- package/src/lib/components/email-detail.d.ts +40 -0
- package/src/lib/components/email-detail.js +1180 -0
- package/src/lib/components/email-detail.js.map +1 -0
- package/src/lib/components/email-edit-drawer.d.ts +54 -0
- package/src/lib/components/email-edit-drawer.js +172 -0
- package/src/lib/components/email-edit-drawer.js.map +1 -0
- package/src/lib/components/email-messages-widget.d.ts +22 -0
- package/src/lib/components/email-messages-widget.js +49 -0
- package/src/lib/components/email-messages-widget.js.map +1 -0
- package/src/lib/components/email-recipients-card.d.ts +50 -0
- package/src/lib/components/email-recipients-card.js +338 -0
- package/src/lib/components/email-recipients-card.js.map +1 -0
- package/src/lib/components/emails-list-card.d.ts +36 -0
- package/src/lib/components/emails-list-card.js +544 -0
- package/src/lib/components/emails-list-card.js.map +1 -0
- package/src/lib/components/experiment-zones.d.ts +78 -0
- package/src/lib/components/experiment-zones.js +65 -0
- package/src/lib/components/experiment-zones.js.map +1 -0
- package/src/lib/components/host-experiments-card.component.d.ts +17 -0
- package/src/lib/components/host-experiments-card.component.js +887 -0
- package/src/lib/components/host-experiments-card.component.js.map +1 -0
- package/src/lib/components/host-marketing-summary-card.component.d.ts +15 -0
- package/src/lib/components/host-marketing-summary-card.component.js +161 -0
- package/src/lib/components/host-marketing-summary-card.component.js.map +1 -0
- package/src/lib/components/host-overlays-card.component.d.ts +19 -0
- package/src/lib/components/host-overlays-card.component.js +783 -0
- package/src/lib/components/host-overlays-card.component.js.map +1 -0
- package/src/lib/components/marketing-console-page.d.ts +28 -0
- package/src/lib/components/marketing-console-page.js +166 -0
- package/src/lib/components/marketing-console-page.js.map +1 -0
- package/src/lib/components/marketing-console-sections.d.ts +34 -0
- package/src/lib/components/marketing-console-sections.js +77 -0
- package/src/lib/components/marketing-console-sections.js.map +1 -0
- package/src/lib/components/overlay-stats-row.component.d.ts +15 -0
- package/src/lib/components/overlay-stats-row.component.js +78 -0
- package/src/lib/components/overlay-stats-row.component.js.map +1 -0
- package/src/lib/components/popup-card.component.d.ts +18 -0
- package/src/lib/components/popup-card.component.js +462 -0
- package/src/lib/components/popup-card.component.js.map +1 -0
- package/src/lib/components/record-attribution-widget.d.ts +35 -0
- package/src/lib/components/record-attribution-widget.js +33 -0
- package/src/lib/components/record-attribution-widget.js.map +1 -0
- package/src/lib/components/site-runtime.d.ts +9 -0
- package/src/lib/components/site-runtime.js +1081 -0
- package/src/lib/components/site-runtime.js.map +1 -0
- package/src/lib/components/use-campaign-send-api.d.ts +35 -0
- package/src/lib/components/use-campaign-send-api.js +99 -0
- package/src/lib/components/use-campaign-send-api.js.map +1 -0
- package/src/lib/components/use-campaign-topic-options.d.ts +20 -0
- package/src/lib/components/use-campaign-topic-options.js +44 -0
- package/src/lib/components/use-campaign-topic-options.js.map +1 -0
- package/src/lib/components/use-emails-hub-path.d.ts +39 -0
- package/src/lib/components/use-emails-hub-path.js +70 -0
- package/src/lib/components/use-emails-hub-path.js.map +1 -0
- package/src/lib/components/use-marketing-hub-path.d.ts +21 -0
- package/src/lib/components/use-marketing-hub-path.js +50 -0
- package/src/lib/components/use-marketing-hub-path.js.map +1 -0
- package/src/lib/components/use-overlay-copy-editor.d.ts +79 -0
- package/src/lib/components/use-overlay-copy-editor.js +110 -0
- package/src/lib/components/use-overlay-copy-editor.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +8 -0
- package/src/lib/constants/bundle-common.js +9 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/model/campaign-membership-figures.d.ts +109 -0
- package/src/lib/model/campaign-membership-figures.js +113 -0
- package/src/lib/model/campaign-membership-figures.js.map +1 -0
- package/src/lib/model/compile-client-automations.d.ts +65 -0
- package/src/lib/model/compile-client-automations.js +95 -0
- package/src/lib/model/compile-client-automations.js.map +1 -0
- package/src/lib/model/experiments.d.ts +130 -0
- package/src/lib/model/experiments.js +186 -0
- package/src/lib/model/experiments.js.map +1 -0
- package/src/lib/model/index.d.ts +26 -0
- package/src/lib/model/index.js +26 -0
- package/src/lib/model/index.js.map +1 -0
- package/src/lib/model/marketing-record-routes.d.ts +6 -0
- package/src/lib/model/marketing-record-routes.js +46 -0
- package/src/lib/model/marketing-record-routes.js.map +1 -0
- package/src/lib/model/overlay-copy.d.ts +62 -0
- package/src/lib/model/overlay-copy.js +78 -0
- package/src/lib/model/overlay-copy.js.map +1 -0
- package/src/lib/model/overlays.d.ts +113 -0
- package/src/lib/model/overlays.js +93 -0
- package/src/lib/model/overlays.js.map +1 -0
- package/src/lib/model/site-contract.d.ts +100 -0
- package/src/lib/model/site-contract.js +23 -0
- package/src/lib/model/site-contract.js.map +1 -0
- package/src/lib/plugin.d.ts +27 -0
- package/src/lib/plugin.js +168 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/preview-props.d.ts +31 -0
- package/src/lib/preview-props.js +54 -0
- package/src/lib/preview-props.js.map +1 -0
- package/src/lib/server/campaign-manage.d.ts +62 -0
- package/src/lib/server/campaign-manage.js +829 -0
- package/src/lib/server/campaign-manage.js.map +1 -0
- package/src/lib/server/campaign-process-scheduled.d.ts +26 -0
- package/src/lib/server/campaign-process-scheduled.js +198 -0
- package/src/lib/server/campaign-process-scheduled.js.map +1 -0
- package/src/lib/server/campaign-recipients.d.ts +55 -0
- package/src/lib/server/campaign-recipients.js +219 -0
- package/src/lib/server/campaign-recipients.js.map +1 -0
- package/src/lib/server/campaign-send.d.ts +487 -0
- package/src/lib/server/campaign-send.js +3157 -0
- package/src/lib/server/campaign-send.js.map +1 -0
- package/src/lib/server/email-campaign-reach.d.ts +174 -0
- package/src/lib/server/email-campaign-reach.js +254 -0
- package/src/lib/server/email-campaign-reach.js.map +1 -0
- package/src/lib/server/email-events.d.ts +27 -0
- package/src/lib/server/email-events.js +714 -0
- package/src/lib/server/email-events.js.map +1 -0
- package/src/lib/server/get-client-automations.d.ts +60 -0
- package/src/lib/server/get-client-automations.js +87 -0
- package/src/lib/server/get-client-automations.js.map +1 -0
- package/src/lib/server/get-overlays.d.ts +28 -0
- package/src/lib/server/get-overlays.js +65 -0
- package/src/lib/server/get-overlays.js.map +1 -0
- package/src/lib/server/get-screen-experiments.d.ts +42 -0
- package/src/lib/server/get-screen-experiments.js +82 -0
- package/src/lib/server/get-screen-experiments.js.map +1 -0
- package/src/lib/server/lists-materialize.d.ts +18 -0
- package/src/lib/server/lists-materialize.js +130 -0
- package/src/lib/server/lists-materialize.js.map +1 -0
- package/src/lib/server/marketing-figures.d.ts +37 -0
- package/src/lib/server/marketing-figures.js +248 -0
- package/src/lib/server/marketing-figures.js.map +1 -0
- package/src/lib/server/site-page-enricher.d.ts +26 -0
- package/src/lib/server/site-page-enricher.js +210 -0
- package/src/lib/server/site-page-enricher.js.map +1 -0
- package/src/lib/server.d.ts +20 -0
- package/src/lib/server.js +152 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/site.d.ts +22 -0
- package/src/lib/site.js +48 -0
- 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
|