ultimate-jekyll-manager 1.0.2 → 1.0.4
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/CHANGELOG.md +4 -0
- package/CLAUDE.md +64 -1
- package/TODO.md +13 -0
- package/dist/assets/css/pages/admin/calendar/index.scss +212 -18
- package/dist/assets/js/pages/admin/calendar/calendar-core.js +535 -95
- package/dist/assets/js/pages/admin/calendar/calendar-events.js +631 -124
- package/dist/assets/js/pages/admin/calendar/calendar-renderer.js +238 -69
- package/dist/assets/js/pages/admin/calendar/campaign-preview.js +100 -0
- package/dist/assets/js/pages/admin/calendar/index.js +3 -16
- package/dist/assets/js/pages/contact/index.js +5 -1
- package/dist/defaults/dist/_includes/admin/sections/sidebar.json +0 -34
- package/dist/defaults/dist/_includes/admin/sections/topbar.json +0 -34
- package/dist/defaults/dist/_includes/themes/classy/backend/sections/topbar.html +1 -72
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +7 -140
- package/dist/defaults/dist/_includes/themes/classy/global/sections/account.html +72 -0
- package/dist/defaults/dist/_layouts/blueprint/admin/calendar/index.html +442 -159
- package/dist/defaults/src/_includes/backend/sections/topbar.json +0 -34
- package/dist/defaults/src/_includes/frontend/sections/nav.json +0 -34
- package/dist/defaults/src/_includes/global/sections/account.json +36 -0
- package/package.json +2 -1
- package/dist/assets/js/pages/admin/notifications/index.js +0 -53
- package/dist/assets/js/pages/admin/notifications/new/index.js +0 -492
- package/dist/defaults/dist/_layouts/blueprint/admin/newsletters/index.html +0 -59
- package/dist/defaults/dist/_layouts/blueprint/admin/newsletters/new.html +0 -46
- package/dist/defaults/dist/_layouts/blueprint/admin/notifications/index.html +0 -103
- package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +0 -399
- package/dist/defaults/dist/pages/admin/newsletters/index.html +0 -7
- package/dist/defaults/dist/pages/admin/newsletters/new.html +0 -7
- package/dist/defaults/dist/pages/admin/notifications/index.html +0 -7
- package/dist/defaults/dist/pages/admin/notifications/new.html +0 -7
|
@@ -6,7 +6,7 @@ layout: themes/classy/admin/core/minimal-viewport-locked
|
|
|
6
6
|
theme:
|
|
7
7
|
header:
|
|
8
8
|
title:
|
|
9
|
-
content: "Calendar"
|
|
9
|
+
content: "Marketing Calendar"
|
|
10
10
|
icon: "calendar-days"
|
|
11
11
|
breadcrumbs:
|
|
12
12
|
items:
|
|
@@ -14,11 +14,18 @@ theme:
|
|
|
14
14
|
href: "/admin"
|
|
15
15
|
- label: "Marketing"
|
|
16
16
|
- label: "Calendar"
|
|
17
|
+
actions:
|
|
18
|
+
items:
|
|
19
|
+
- label: "Create Campaign"
|
|
20
|
+
icon: "plus"
|
|
21
|
+
color: "primary"
|
|
22
|
+
attributes:
|
|
23
|
+
- ["id", "btn-create-campaign"]
|
|
17
24
|
|
|
18
25
|
### REGULAR PAGES ###
|
|
19
26
|
meta:
|
|
20
|
-
title: "Calendar - Admin"
|
|
21
|
-
description: "
|
|
27
|
+
title: "Marketing Calendar - Admin"
|
|
28
|
+
description: "Schedule and manage marketing campaigns — emails and push notifications"
|
|
22
29
|
breadcrumb: "Calendar"
|
|
23
30
|
|
|
24
31
|
### ICON PRE-RENDERING ###
|
|
@@ -28,7 +35,6 @@ prerender_icons:
|
|
|
28
35
|
- name: "plus"
|
|
29
36
|
- name: "pen"
|
|
30
37
|
- name: "trash"
|
|
31
|
-
- name: "grip-dots-vertical"
|
|
32
38
|
- name: "clock"
|
|
33
39
|
- name: "envelope"
|
|
34
40
|
- name: "bell"
|
|
@@ -38,8 +44,22 @@ prerender_icons:
|
|
|
38
44
|
- name: "calendar"
|
|
39
45
|
- name: "grid-2"
|
|
40
46
|
- name: "mobile"
|
|
41
|
-
- name: "
|
|
42
|
-
- name: "
|
|
47
|
+
- name: "circle-check"
|
|
48
|
+
- name: "triangle-exclamation"
|
|
49
|
+
- name: "xmark"
|
|
50
|
+
- name: "rotate-right"
|
|
51
|
+
- name: "eye"
|
|
52
|
+
- name: "link"
|
|
53
|
+
- name: "tags"
|
|
54
|
+
- name: "users"
|
|
55
|
+
- name: "bullhorn"
|
|
56
|
+
- name: "code"
|
|
57
|
+
- name: "sliders"
|
|
58
|
+
- name: "arrow-up-right-from-square"
|
|
59
|
+
- name: "repeat"
|
|
60
|
+
- name: "wifi"
|
|
61
|
+
- name: "battery-full"
|
|
62
|
+
- name: "table-list"
|
|
43
63
|
---
|
|
44
64
|
|
|
45
65
|
<!-- Calendar Root -->
|
|
@@ -51,241 +71,479 @@ prerender_icons:
|
|
|
51
71
|
<div id="calendar-grid" class="flex-grow-1 overflow-hidden position-relative"></div>
|
|
52
72
|
</div>
|
|
53
73
|
|
|
54
|
-
<!--
|
|
55
|
-
<div class="modal fade" id="
|
|
74
|
+
<!-- Campaign Editor Modal -->
|
|
75
|
+
<div class="modal fade" id="campaign-editor-modal" tabindex="-1" aria-labelledby="campaign-modal-title" aria-hidden="true">
|
|
56
76
|
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
|
57
77
|
<div class="modal-content">
|
|
58
78
|
<div class="modal-header">
|
|
59
|
-
<h5 class="modal-title" id="
|
|
79
|
+
<h5 class="modal-title" id="campaign-modal-title">
|
|
60
80
|
{% uj_icon "plus", "fa-md me-2" %}
|
|
61
|
-
<span id="
|
|
81
|
+
<span id="campaign-modal-title-text">Create Campaign</span>
|
|
62
82
|
</h5>
|
|
63
83
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
64
84
|
</div>
|
|
65
85
|
<div class="modal-body">
|
|
66
|
-
<form id="
|
|
86
|
+
<form id="campaign-editor-form" novalidate onsubmit="return false">
|
|
67
87
|
|
|
68
|
-
<!--
|
|
88
|
+
<!-- Campaign Type -->
|
|
69
89
|
<h6 class="mb-3">
|
|
70
|
-
{% uj_icon "
|
|
71
|
-
|
|
90
|
+
{% uj_icon "bullhorn", "fa-sm me-2 text-info" %}
|
|
91
|
+
Campaign Type
|
|
72
92
|
</h6>
|
|
73
93
|
<div class="row mb-4">
|
|
74
94
|
<div class="col-6">
|
|
75
|
-
<input type="radio" class="btn-check" name="
|
|
76
|
-
<label class="btn btn-outline-adaptive w-100 d-flex align-items-center justify-content-center" for="
|
|
95
|
+
<input type="radio" class="btn-check" name="campaign.type" id="campaign-type-email" value="email" checked autocomplete="off">
|
|
96
|
+
<label class="btn btn-outline-adaptive w-100 d-flex align-items-center justify-content-center" for="campaign-type-email">
|
|
77
97
|
{% uj_icon "envelope", "fa-sm me-2" %}
|
|
78
|
-
|
|
98
|
+
Email
|
|
79
99
|
</label>
|
|
80
100
|
</div>
|
|
81
101
|
<div class="col-6">
|
|
82
|
-
<input type="radio" class="btn-check" name="
|
|
83
|
-
<label class="btn btn-outline-adaptive w-100 d-flex align-items-center justify-content-center" for="
|
|
102
|
+
<input type="radio" class="btn-check" name="campaign.type" id="campaign-type-push" value="push" autocomplete="off">
|
|
103
|
+
<label class="btn btn-outline-adaptive w-100 d-flex align-items-center justify-content-center" for="campaign-type-push">
|
|
84
104
|
{% uj_icon "bell", "fa-sm me-2" %}
|
|
85
|
-
Notification
|
|
105
|
+
Push Notification
|
|
86
106
|
</label>
|
|
87
107
|
</div>
|
|
88
108
|
</div>
|
|
89
109
|
|
|
90
|
-
<!-- Content -->
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
110
|
+
<!-- Content: Edit / Preview tabs -->
|
|
111
|
+
<ul class="nav nav-tabs mb-3" id="campaign-content-tabs" role="tablist">
|
|
112
|
+
<li class="nav-item" role="presentation">
|
|
113
|
+
<button class="nav-link active" id="tab-edit" data-bs-toggle="tab" data-bs-target="#panel-edit" type="button" role="tab">
|
|
114
|
+
{% uj_icon "pen", "fa-sm me-1" %} Edit
|
|
115
|
+
</button>
|
|
116
|
+
</li>
|
|
117
|
+
<li class="nav-item" role="presentation">
|
|
118
|
+
<button class="nav-link" id="tab-preview" data-bs-toggle="tab" data-bs-target="#panel-preview" type="button" role="tab">
|
|
119
|
+
{% uj_icon "eye", "fa-sm me-1" %} Preview
|
|
120
|
+
</button>
|
|
121
|
+
</li>
|
|
122
|
+
</ul>
|
|
123
|
+
|
|
124
|
+
<div class="tab-content">
|
|
125
|
+
<!-- Edit Tab -->
|
|
126
|
+
<div class="tab-pane fade show active" id="panel-edit" role="tabpanel">
|
|
127
|
+
<div class="mb-3">
|
|
128
|
+
<label for="campaign-name" class="form-label">
|
|
129
|
+
Campaign Name <span class="text-danger">*</span>
|
|
130
|
+
</label>
|
|
131
|
+
<input type="text"
|
|
132
|
+
class="form-control"
|
|
133
|
+
id="campaign-name"
|
|
134
|
+
name="campaign.name"
|
|
135
|
+
placeholder="e.g. Spring Sale"
|
|
136
|
+
minlength="3"
|
|
137
|
+
maxlength="100"
|
|
138
|
+
required>
|
|
139
|
+
<div class="invalid-feedback">Campaign name is required (3-100 characters)</div>
|
|
140
|
+
</div>
|
|
94
141
|
|
|
142
|
+
<div class="mb-3">
|
|
143
|
+
<label for="campaign-subject" class="form-label">
|
|
144
|
+
Subject <span class="text-danger">*</span>
|
|
145
|
+
<small class="text-muted fw-normal ms-1" id="campaign-subject-hint">(email subject line)</small>
|
|
146
|
+
</label>
|
|
147
|
+
<input type="text"
|
|
148
|
+
class="form-control"
|
|
149
|
+
id="campaign-subject"
|
|
150
|
+
name="campaign.subject"
|
|
151
|
+
placeholder="e.g. 50% Off Premium!"
|
|
152
|
+
minlength="3"
|
|
153
|
+
maxlength="200"
|
|
154
|
+
required>
|
|
155
|
+
<div class="invalid-feedback">Subject is required</div>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<!-- Email-only fields -->
|
|
159
|
+
<div id="email-fields">
|
|
160
|
+
<div class="mb-3">
|
|
161
|
+
<label for="campaign-preheader" class="form-label">
|
|
162
|
+
Preheader
|
|
163
|
+
<small class="text-muted fw-normal ms-1">(preview text)</small>
|
|
164
|
+
</label>
|
|
165
|
+
<input type="text"
|
|
166
|
+
class="form-control"
|
|
167
|
+
id="campaign-preheader"
|
|
168
|
+
name="campaign.preheader"
|
|
169
|
+
placeholder="Brief preview text shown in inbox"
|
|
170
|
+
maxlength="200">
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="mb-3">
|
|
174
|
+
<label for="campaign-content" class="form-label">
|
|
175
|
+
Content
|
|
176
|
+
<small class="text-muted fw-normal ms-1">(markdown)</small>
|
|
177
|
+
</label>
|
|
178
|
+
<textarea class="form-control font-monospace"
|
|
179
|
+
id="campaign-content"
|
|
180
|
+
name="campaign.content"
|
|
181
|
+
rows="6"
|
|
182
|
+
placeholder="# Hello Check out our **sale**!"></textarea>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div class="row mb-3">
|
|
186
|
+
<div class="col-md-6">
|
|
187
|
+
<label for="campaign-template" class="form-label">Template</label>
|
|
188
|
+
<select class="form-select" id="campaign-template" name="campaign.template">
|
|
189
|
+
<option value="default" selected>Default</option>
|
|
190
|
+
<option value="main/basic/card">Card</option>
|
|
191
|
+
<option value="main/basic/plain">Plain</option>
|
|
192
|
+
</select>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="col-md-6">
|
|
195
|
+
<label for="campaign-sender" class="form-label">Sender</label>
|
|
196
|
+
<select class="form-select" id="campaign-sender" name="campaign.sender">
|
|
197
|
+
<option value="marketing" selected>Marketing</option>
|
|
198
|
+
<option value="newsletter">Newsletter</option>
|
|
199
|
+
<option value="hello">Hello</option>
|
|
200
|
+
<option value="orders">Orders</option>
|
|
201
|
+
</select>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<!-- Push-only fields -->
|
|
207
|
+
<div id="push-fields" class="d-none">
|
|
208
|
+
<div class="mb-3">
|
|
209
|
+
<label for="campaign-icon" class="form-label">
|
|
210
|
+
Icon URL
|
|
211
|
+
</label>
|
|
212
|
+
<input type="url"
|
|
213
|
+
class="form-control"
|
|
214
|
+
id="campaign-icon"
|
|
215
|
+
name="campaign.icon"
|
|
216
|
+
placeholder="https://example.com/icon.png"
|
|
217
|
+
pattern="https?://.+"
|
|
218
|
+
title="URL must start with http:// or https://">
|
|
219
|
+
<div class="invalid-feedback">Please provide a valid icon URL</div>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<div class="mb-3">
|
|
223
|
+
<label for="campaign-click-action" class="form-label">
|
|
224
|
+
Click Action URL
|
|
225
|
+
</label>
|
|
226
|
+
<input type="url"
|
|
227
|
+
class="form-control"
|
|
228
|
+
id="campaign-click-action"
|
|
229
|
+
name="campaign.clickAction"
|
|
230
|
+
placeholder="https://example.com/landing"
|
|
231
|
+
pattern="https?://.+"
|
|
232
|
+
title="URL must start with http:// or https://">
|
|
233
|
+
<div class="invalid-feedback">Please provide a valid URL</div>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div class="mb-3">
|
|
237
|
+
<label for="campaign-push-tags" class="form-label">
|
|
238
|
+
{% uj_icon "tags", "fa-sm me-1 text-info" %}
|
|
239
|
+
Filter by Tags
|
|
240
|
+
<small class="text-muted fw-normal ms-1">(comma-separated)</small>
|
|
241
|
+
</label>
|
|
242
|
+
<input type="text"
|
|
243
|
+
class="form-control"
|
|
244
|
+
id="campaign-push-tags"
|
|
245
|
+
name="campaign.filters.tags"
|
|
246
|
+
placeholder="e.g. premium, active">
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<div class="mb-3">
|
|
250
|
+
<label for="campaign-push-owner" class="form-label">
|
|
251
|
+
Owner UID
|
|
252
|
+
<small class="text-muted fw-normal ms-1">(optional, for testing)</small>
|
|
253
|
+
</label>
|
|
254
|
+
<input type="text"
|
|
255
|
+
class="form-control"
|
|
256
|
+
id="campaign-push-owner"
|
|
257
|
+
name="campaign.filters.owner"
|
|
258
|
+
placeholder="User UID for targeted test send">
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<!-- Preview Tab -->
|
|
264
|
+
<div class="tab-pane fade" id="panel-preview" role="tabpanel">
|
|
265
|
+
<div id="campaign-preview-container">
|
|
266
|
+
<div class="text-center text-muted py-4">
|
|
267
|
+
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
|
|
268
|
+
Loading preview...
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<!-- Discount Code -->
|
|
95
275
|
<div class="mb-3">
|
|
96
|
-
<label for="
|
|
97
|
-
|
|
276
|
+
<label for="campaign-discount-code" class="form-label">
|
|
277
|
+
Discount Code
|
|
278
|
+
<small class="text-muted fw-normal ms-1">(optional)</small>
|
|
98
279
|
</label>
|
|
99
280
|
<input type="text"
|
|
100
281
|
class="form-control"
|
|
101
|
-
id="
|
|
102
|
-
name="
|
|
103
|
-
placeholder="
|
|
104
|
-
minlength="3"
|
|
105
|
-
maxlength="100"
|
|
106
|
-
required>
|
|
107
|
-
<div class="invalid-feedback">Title is required (3-100 characters)</div>
|
|
282
|
+
id="campaign-discount-code"
|
|
283
|
+
name="campaign.discountCode"
|
|
284
|
+
placeholder="e.g. UPGRADE15">
|
|
108
285
|
</div>
|
|
109
286
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
287
|
+
<!-- Test Mode -->
|
|
288
|
+
<div class="form-check mb-4">
|
|
289
|
+
<input class="form-check-input"
|
|
290
|
+
type="checkbox"
|
|
291
|
+
id="campaign-test"
|
|
292
|
+
name="campaign.test">
|
|
293
|
+
<label class="form-check-label" for="campaign-test">
|
|
294
|
+
Test mode
|
|
113
295
|
</label>
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
rows="4"
|
|
118
|
-
placeholder="Enter event content or description"></textarea>
|
|
296
|
+
<small class="d-block text-muted mt-1">
|
|
297
|
+
Send only to admin/test recipients instead of the full audience. Use this to preview the campaign before going live.
|
|
298
|
+
</small>
|
|
119
299
|
</div>
|
|
120
300
|
|
|
121
301
|
<!-- Schedule -->
|
|
122
|
-
<h6 class="mb-3">
|
|
302
|
+
<h6 class="mb-3 mt-4">
|
|
123
303
|
{% uj_icon "clock", "fa-sm me-2 text-info" %}
|
|
124
304
|
Schedule
|
|
125
305
|
</h6>
|
|
126
306
|
|
|
127
307
|
<div class="row mb-3">
|
|
128
|
-
<div class="col-md-
|
|
129
|
-
<label for="
|
|
308
|
+
<div class="col-md-5">
|
|
309
|
+
<label for="campaign-date" class="form-label">
|
|
130
310
|
Date <span class="text-danger">*</span>
|
|
131
311
|
</label>
|
|
132
312
|
<input type="date"
|
|
133
313
|
class="form-control"
|
|
134
|
-
id="
|
|
135
|
-
name="
|
|
314
|
+
id="campaign-date"
|
|
315
|
+
name="campaign.date"
|
|
136
316
|
required>
|
|
137
317
|
<div class="invalid-feedback">Date is required</div>
|
|
138
318
|
</div>
|
|
139
319
|
<div class="col-md-4">
|
|
140
|
-
<label for="
|
|
320
|
+
<label for="campaign-time" class="form-label">
|
|
141
321
|
Time <span class="text-danger">*</span>
|
|
142
322
|
</label>
|
|
143
323
|
<input type="time"
|
|
144
324
|
class="form-control"
|
|
145
|
-
id="
|
|
146
|
-
name="
|
|
325
|
+
id="campaign-time"
|
|
326
|
+
name="campaign.time"
|
|
147
327
|
value="09:00"
|
|
148
328
|
required>
|
|
149
329
|
<div class="invalid-feedback">Time is required</div>
|
|
150
330
|
</div>
|
|
151
|
-
<div class="col-md-
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
class="form-control"
|
|
157
|
-
id="event-duration"
|
|
158
|
-
name="event.duration"
|
|
159
|
-
value="60"
|
|
160
|
-
min="5"
|
|
161
|
-
max="1440"
|
|
162
|
-
step="5">
|
|
331
|
+
<div class="col-md-3 d-flex align-items-end">
|
|
332
|
+
<button type="button" class="btn btn-sm btn-outline-primary w-100" id="btn-send-now">
|
|
333
|
+
{% uj_icon "paper-plane", "fa-sm me-1" %}
|
|
334
|
+
Send Now
|
|
335
|
+
</button>
|
|
163
336
|
</div>
|
|
164
337
|
</div>
|
|
165
338
|
|
|
166
|
-
<!--
|
|
339
|
+
<!-- Recurrence -->
|
|
167
340
|
<h6 class="mb-3 mt-4">
|
|
168
|
-
{% uj_icon "
|
|
169
|
-
|
|
341
|
+
{% uj_icon "repeat", "fa-sm me-2 text-info" %}
|
|
342
|
+
Recurrence
|
|
343
|
+
<small class="text-muted fw-normal ms-1">(optional)</small>
|
|
170
344
|
</h6>
|
|
171
345
|
|
|
172
|
-
<div class="mb-3">
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
346
|
+
<div class="form-check mb-3">
|
|
347
|
+
<input class="form-check-input"
|
|
348
|
+
type="checkbox"
|
|
349
|
+
id="campaign-recurring"
|
|
350
|
+
name="campaign.recurring">
|
|
351
|
+
<label class="form-check-label" for="campaign-recurring">
|
|
352
|
+
Make this a recurring campaign
|
|
353
|
+
</label>
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<div id="recurrence-fields" class="d-none">
|
|
357
|
+
<div class="row mb-3">
|
|
358
|
+
<div class="col-md-4">
|
|
359
|
+
<label for="campaign-recurrence-pattern" class="form-label">Pattern</label>
|
|
360
|
+
<select class="form-select" id="campaign-recurrence-pattern" name="campaign.recurrence.pattern">
|
|
361
|
+
<option value="daily">Daily</option>
|
|
362
|
+
<option value="weekly">Weekly</option>
|
|
363
|
+
<option value="monthly" selected>Monthly</option>
|
|
364
|
+
<option value="quarterly">Quarterly</option>
|
|
365
|
+
<option value="yearly">Yearly</option>
|
|
366
|
+
</select>
|
|
367
|
+
</div>
|
|
368
|
+
<div class="col-md-4">
|
|
369
|
+
<label for="campaign-recurrence-hour" class="form-label">Hour (UTC)</label>
|
|
370
|
+
<input type="number"
|
|
371
|
+
class="form-control"
|
|
372
|
+
id="campaign-recurrence-hour"
|
|
373
|
+
name="campaign.recurrence.hour"
|
|
374
|
+
value="14"
|
|
375
|
+
min="0"
|
|
376
|
+
max="23">
|
|
377
|
+
</div>
|
|
378
|
+
<div class="col-md-4">
|
|
379
|
+
<label for="campaign-recurrence-day" class="form-label">
|
|
380
|
+
Day
|
|
381
|
+
<small class="text-muted fw-normal ms-1" id="recurrence-day-hint">(of month)</small>
|
|
382
|
+
</label>
|
|
383
|
+
<input type="number"
|
|
384
|
+
class="form-control"
|
|
385
|
+
id="campaign-recurrence-day"
|
|
386
|
+
name="campaign.recurrence.day"
|
|
387
|
+
value="1"
|
|
388
|
+
min="0"
|
|
389
|
+
max="31">
|
|
390
|
+
</div>
|
|
183
391
|
</div>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
392
|
+
|
|
393
|
+
<div class="row mb-3 d-none" id="recurrence-month-row">
|
|
394
|
+
<div class="col-md-4">
|
|
395
|
+
<label for="campaign-recurrence-month" class="form-label">Month</label>
|
|
396
|
+
<select class="form-select" id="campaign-recurrence-month" name="campaign.recurrence.month">
|
|
397
|
+
<option value="1">January</option>
|
|
398
|
+
<option value="2">February</option>
|
|
399
|
+
<option value="3">March</option>
|
|
400
|
+
<option value="4">April</option>
|
|
401
|
+
<option value="5">May</option>
|
|
402
|
+
<option value="6">June</option>
|
|
403
|
+
<option value="7">July</option>
|
|
404
|
+
<option value="8">August</option>
|
|
405
|
+
<option value="9">September</option>
|
|
406
|
+
<option value="10">October</option>
|
|
407
|
+
<option value="11">November</option>
|
|
408
|
+
<option value="12">December</option>
|
|
409
|
+
</select>
|
|
410
|
+
</div>
|
|
193
411
|
</div>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
name="event.data.audience.type"
|
|
198
|
-
id="audience-test"
|
|
199
|
-
value="test">
|
|
200
|
-
<label class="form-check-label" for="audience-test">
|
|
201
|
-
Test Users Only
|
|
202
|
-
</label>
|
|
412
|
+
|
|
413
|
+
<div class="alert alert-info small mb-3" id="recurrence-info">
|
|
414
|
+
This campaign will repeat automatically. Editing changes all future sends.
|
|
203
415
|
</div>
|
|
204
416
|
</div>
|
|
205
417
|
|
|
206
|
-
<!--
|
|
418
|
+
<!-- Targeting -->
|
|
207
419
|
<h6 class="mb-3 mt-4">
|
|
208
|
-
|
|
420
|
+
{% uj_icon "users", "fa-sm me-2 text-success" %}
|
|
421
|
+
Targeting
|
|
209
422
|
</h6>
|
|
210
423
|
|
|
211
|
-
<div class="
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
type="checkbox"
|
|
216
|
-
id="channel-push"
|
|
217
|
-
name="event.data.channels.push"
|
|
218
|
-
checked>
|
|
219
|
-
<label class="form-check-label" for="channel-push">
|
|
220
|
-
{% uj_icon "mobile", "fa-sm me-1 text-primary" %}
|
|
221
|
-
Push
|
|
222
|
-
</label>
|
|
223
|
-
</div>
|
|
224
|
-
</div>
|
|
225
|
-
<div class="col-6 col-md-3">
|
|
226
|
-
<div class="form-check">
|
|
227
|
-
<input class="form-check-input"
|
|
228
|
-
type="checkbox"
|
|
229
|
-
id="channel-email"
|
|
230
|
-
name="event.data.channels.email">
|
|
231
|
-
<label class="form-check-label" for="channel-email">
|
|
232
|
-
{% uj_icon "envelope", "fa-sm me-1 text-info" %}
|
|
233
|
-
Email
|
|
234
|
-
</label>
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
<div class="col-6 col-md-3">
|
|
424
|
+
<div class="mb-3" id="email-targeting">
|
|
425
|
+
<label class="form-label">Providers</label>
|
|
426
|
+
<small class="d-block text-muted mb-2">Which services to send through. Leave unchecked to use all enabled providers.</small>
|
|
427
|
+
<div class="d-flex gap-3">
|
|
238
428
|
<div class="form-check">
|
|
239
429
|
<input class="form-check-input"
|
|
240
430
|
type="checkbox"
|
|
241
|
-
id="
|
|
242
|
-
name="
|
|
243
|
-
<label class="form-check-label" for="
|
|
244
|
-
|
|
245
|
-
SMS
|
|
431
|
+
id="campaign-provider-sendgrid"
|
|
432
|
+
name="campaign.providers.sendgrid">
|
|
433
|
+
<label class="form-check-label" for="campaign-provider-sendgrid">
|
|
434
|
+
SendGrid
|
|
246
435
|
</label>
|
|
247
436
|
</div>
|
|
248
|
-
</div>
|
|
249
|
-
<div class="col-6 col-md-3">
|
|
250
437
|
<div class="form-check">
|
|
251
438
|
<input class="form-check-input"
|
|
252
439
|
type="checkbox"
|
|
253
|
-
id="
|
|
254
|
-
name="
|
|
255
|
-
<label class="form-check-label" for="
|
|
256
|
-
|
|
257
|
-
In-App
|
|
440
|
+
id="campaign-provider-beehiiv"
|
|
441
|
+
name="campaign.providers.beehiiv">
|
|
442
|
+
<label class="form-check-label" for="campaign-provider-beehiiv">
|
|
443
|
+
Beehiiv
|
|
258
444
|
</label>
|
|
259
445
|
</div>
|
|
260
446
|
</div>
|
|
261
447
|
</div>
|
|
262
448
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
449
|
+
<div class="form-check mb-2">
|
|
450
|
+
<input class="form-check-input"
|
|
451
|
+
type="checkbox"
|
|
452
|
+
id="campaign-all"
|
|
453
|
+
name="campaign.all">
|
|
454
|
+
<label class="form-check-label" for="campaign-all">
|
|
455
|
+
Target all contacts
|
|
456
|
+
<small class="text-muted fw-normal ms-1">(SendGrid only — overrides lists/segments)</small>
|
|
457
|
+
</label>
|
|
458
|
+
</div>
|
|
459
|
+
|
|
460
|
+
<div class="mb-3">
|
|
461
|
+
<label for="campaign-lists" class="form-label">
|
|
462
|
+
Lists
|
|
463
|
+
<small class="text-muted fw-normal ms-1">(SendGrid list IDs, comma-separated — empty = brand default list)</small>
|
|
464
|
+
</label>
|
|
465
|
+
<input type="text"
|
|
466
|
+
class="form-control"
|
|
467
|
+
id="campaign-lists"
|
|
468
|
+
name="campaign.lists"
|
|
469
|
+
placeholder="Leave empty for default brand list">
|
|
470
|
+
</div>
|
|
471
|
+
|
|
472
|
+
<div class="mb-3">
|
|
473
|
+
<label for="campaign-segments" class="form-label">
|
|
474
|
+
Segments
|
|
475
|
+
<small class="text-muted fw-normal ms-1">(comma-separated IDs)</small>
|
|
476
|
+
</label>
|
|
477
|
+
<input type="text"
|
|
478
|
+
class="form-control"
|
|
479
|
+
id="campaign-segments"
|
|
480
|
+
name="campaign.segments"
|
|
481
|
+
placeholder="e.g. seg_abc123, seg_def456">
|
|
482
|
+
</div>
|
|
483
|
+
|
|
484
|
+
<div class="mb-3">
|
|
485
|
+
<label for="campaign-exclude-segments" class="form-label">
|
|
486
|
+
Exclude Segments
|
|
487
|
+
<small class="text-muted fw-normal ms-1">(comma-separated IDs)</small>
|
|
488
|
+
</label>
|
|
489
|
+
<input type="text"
|
|
490
|
+
class="form-control"
|
|
491
|
+
id="campaign-exclude-segments"
|
|
492
|
+
name="campaign.excludeSegments"
|
|
493
|
+
placeholder="e.g. seg_unsubscribed">
|
|
494
|
+
</div>
|
|
495
|
+
|
|
496
|
+
<!-- Advanced Settings (collapsible) -->
|
|
497
|
+
<h6 class="mb-3 mt-4">
|
|
498
|
+
<a class="text-decoration-none" data-bs-toggle="collapse" href="#advanced-settings" role="button" aria-expanded="false">
|
|
499
|
+
{% uj_icon "sliders", "fa-sm me-2 text-info" %}
|
|
500
|
+
Advanced Settings
|
|
501
|
+
<small class="text-muted fw-normal ms-1">(optional)</small>
|
|
502
|
+
</a>
|
|
266
503
|
</h6>
|
|
267
504
|
|
|
268
|
-
<div class="
|
|
269
|
-
<div class="
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
<
|
|
273
|
-
|
|
274
|
-
|
|
505
|
+
<div class="collapse" id="advanced-settings">
|
|
506
|
+
<div class="row mb-3">
|
|
507
|
+
<div class="col-md-6">
|
|
508
|
+
<label for="campaign-group" class="form-label">ASM Group</label>
|
|
509
|
+
<input type="text"
|
|
510
|
+
class="form-control"
|
|
511
|
+
id="campaign-group"
|
|
512
|
+
name="campaign.group"
|
|
513
|
+
placeholder="e.g. marketing">
|
|
514
|
+
</div>
|
|
515
|
+
<div class="col-md-6">
|
|
516
|
+
<label for="campaign-categories" class="form-label">
|
|
517
|
+
Categories
|
|
518
|
+
<small class="text-muted fw-normal ms-1">(comma-separated)</small>
|
|
519
|
+
</label>
|
|
520
|
+
<input type="text"
|
|
521
|
+
class="form-control"
|
|
522
|
+
id="campaign-categories"
|
|
523
|
+
name="campaign.categories"
|
|
524
|
+
placeholder="e.g. marketing, q1-launch">
|
|
525
|
+
</div>
|
|
275
526
|
</div>
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
<
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
<
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
<
|
|
527
|
+
|
|
528
|
+
<div class="mb-3">
|
|
529
|
+
<label class="form-label">UTM Overrides</label>
|
|
530
|
+
<div class="row g-2" id="utm-fields">
|
|
531
|
+
<div class="col-md-6">
|
|
532
|
+
<input type="text" class="form-control form-control-sm" name="campaign.utm.utm_source" placeholder="utm_source">
|
|
533
|
+
</div>
|
|
534
|
+
<div class="col-md-6">
|
|
535
|
+
<input type="text" class="form-control form-control-sm" name="campaign.utm.utm_medium" placeholder="utm_medium">
|
|
536
|
+
</div>
|
|
537
|
+
<div class="col-md-6">
|
|
538
|
+
<input type="text" class="form-control form-control-sm" name="campaign.utm.utm_campaign" placeholder="utm_campaign">
|
|
539
|
+
</div>
|
|
540
|
+
<div class="col-md-6">
|
|
541
|
+
<input type="text" class="form-control form-control-sm" name="campaign.utm.utm_term" placeholder="utm_term">
|
|
542
|
+
</div>
|
|
543
|
+
<div class="col-md-6">
|
|
544
|
+
<input type="text" class="form-control form-control-sm" name="campaign.utm.utm_content" placeholder="utm_content">
|
|
545
|
+
</div>
|
|
287
546
|
</div>
|
|
288
|
-
<input type="hidden" name="event.color" id="event-color" value="#4CAF50">
|
|
289
547
|
</div>
|
|
290
548
|
</div>
|
|
291
549
|
|
|
@@ -293,19 +551,44 @@ prerender_icons:
|
|
|
293
551
|
</div>
|
|
294
552
|
<div class="modal-footer d-flex justify-content-between">
|
|
295
553
|
<div>
|
|
296
|
-
<button type="button" class="btn btn-outline-danger d-none" id="btn-delete-
|
|
554
|
+
<button type="button" class="btn btn-outline-danger d-none" id="btn-delete-campaign">
|
|
297
555
|
{% uj_icon "trash", "fa-sm me-1" %}
|
|
298
556
|
Delete
|
|
299
557
|
</button>
|
|
300
558
|
</div>
|
|
301
559
|
<div class="d-flex gap-2">
|
|
302
560
|
<button type="button" class="btn btn-outline-adaptive" data-bs-dismiss="modal">Cancel</button>
|
|
303
|
-
<button type="submit" form="
|
|
561
|
+
<button type="submit" form="campaign-editor-form" class="btn btn-adaptive" id="btn-save-campaign">
|
|
304
562
|
{% uj_icon "paper-plane", "fa-sm me-1" %}
|
|
305
|
-
<span class="button-text">Save
|
|
563
|
+
<span class="button-text">Save Campaign</span>
|
|
306
564
|
</button>
|
|
307
565
|
</div>
|
|
308
566
|
</div>
|
|
309
567
|
</div>
|
|
310
568
|
</div>
|
|
311
569
|
</div>
|
|
570
|
+
|
|
571
|
+
<!-- Campaign Results Modal (read-only for sent/failed) -->
|
|
572
|
+
<div class="modal fade" id="campaign-results-modal" tabindex="-1" aria-labelledby="campaign-results-title" aria-hidden="true">
|
|
573
|
+
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
|
574
|
+
<div class="modal-content">
|
|
575
|
+
<div class="modal-header">
|
|
576
|
+
<h5 class="modal-title" id="campaign-results-title">
|
|
577
|
+
{% uj_icon "eye", "fa-md me-2" %}
|
|
578
|
+
<span id="campaign-results-title-text">Campaign Details</span>
|
|
579
|
+
</h5>
|
|
580
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
581
|
+
</div>
|
|
582
|
+
<div class="modal-body" id="campaign-results-body">
|
|
583
|
+
<!-- Populated dynamically -->
|
|
584
|
+
</div>
|
|
585
|
+
<div class="modal-footer">
|
|
586
|
+
<button type="button" class="btn btn-outline-danger d-none" id="btn-retry-campaign">
|
|
587
|
+
{% uj_icon "rotate-right", "fa-sm me-1" %}
|
|
588
|
+
Retry (Create New)
|
|
589
|
+
</button>
|
|
590
|
+
<button type="button" class="btn btn-outline-adaptive" data-bs-dismiss="modal">Close</button>
|
|
591
|
+
</div>
|
|
592
|
+
</div>
|
|
593
|
+
</div>
|
|
594
|
+
</div>
|