ultimate-jekyll-manager 0.0.118 → 0.0.120
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/CLAUDE.md +409 -23
- package/README.md +171 -2
- package/TODO.md +10 -2
- package/_backup/form-manager.backup.js +1020 -0
- package/dist/assets/js/core/auth.js +5 -4
- package/dist/assets/js/core/cookieconsent.js +24 -17
- package/dist/assets/js/core/exit-popup.js +15 -12
- package/dist/assets/js/core/social-sharing.js +8 -4
- package/dist/assets/js/libs/auth/pages.js +78 -149
- package/dist/assets/js/libs/dev.js +192 -129
- package/dist/assets/js/libs/form-manager.js +643 -775
- package/dist/assets/js/pages/account/index.js +3 -2
- package/dist/assets/js/pages/account/sections/api-keys.js +37 -52
- package/dist/assets/js/pages/account/sections/connections.js +37 -46
- package/dist/assets/js/pages/account/sections/delete.js +57 -78
- package/dist/assets/js/pages/account/sections/profile.js +37 -56
- package/dist/assets/js/pages/account/sections/security.js +102 -125
- package/dist/assets/js/pages/admin/notifications/new/index.js +73 -151
- package/dist/assets/js/pages/blog/index.js +33 -53
- package/dist/assets/js/pages/contact/index.js +112 -173
- package/dist/assets/js/pages/download/index.js +39 -86
- package/dist/assets/js/pages/oauth2/index.js +17 -17
- package/dist/assets/js/pages/payment/checkout/index.js +23 -36
- package/dist/assets/js/pages/pricing/index.js +5 -2
- package/dist/assets/js/pages/test/libraries/form-manager/index.js +194 -0
- package/dist/assets/themes/classy/css/components/_cards.scss +2 -2
- package/dist/defaults/_.env +6 -0
- package/dist/defaults/_.gitignore +7 -1
- package/dist/defaults/dist/_includes/core/body.html +5 -13
- package/dist/defaults/dist/_includes/core/foot.html +1 -0
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +51 -36
- package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +13 -2
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/about.html +84 -42
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/account/index.html +26 -21
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/auth/signin.html +2 -2
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/auth/signup.html +2 -2
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/index.html +72 -58
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/post.html +46 -29
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html +46 -53
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +111 -73
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/index.html +111 -56
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +127 -81
- package/dist/defaults/dist/pages/test/libraries/form-manager.html +181 -0
- package/dist/defaults/dist/pages/test/libraries/lazy-loading.html +1 -1
- package/dist/gulp/tasks/defaults.js +210 -1
- package/dist/gulp/tasks/serve.js +18 -0
- package/dist/lib/logger.js +1 -1
- package/firebase-debug.log +770 -0
- package/package.json +6 -6
- package/.playwright-mcp/page-2025-10-22T19-11-27-666Z.png +0 -0
- package/.playwright-mcp/page-2025-10-22T19-11-57-357Z.png +0 -0
|
@@ -123,47 +123,31 @@ function trackAddPaymentInfo(product, price, billingCycle, paymentMethod) {
|
|
|
123
123
|
function setupEventListeners() {
|
|
124
124
|
// Initialize FormManager
|
|
125
125
|
formManager = new FormManager('#checkout-form', {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
autoReady: false, // We'll call ready() after initialization
|
|
127
|
+
allowResubmit: false,
|
|
128
|
+
submittingText: 'Processing...',
|
|
129
|
+
submittedText: 'Redirecting...',
|
|
130
130
|
});
|
|
131
131
|
|
|
132
132
|
// Listen for form field changes
|
|
133
|
-
formManager.
|
|
134
|
-
const { fieldName, fieldValue, data } = event.detail;
|
|
135
|
-
|
|
133
|
+
formManager.on('change', ({ name, value }) => {
|
|
136
134
|
// Handle billing cycle changes
|
|
137
|
-
if (
|
|
138
|
-
handleBillingCycleChange(
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Handle non-submit button clicks
|
|
143
|
-
formManager.addEventListener('button', (event) => {
|
|
144
|
-
const { action } = event.detail;
|
|
145
|
-
|
|
146
|
-
if (action === 'apply-discount') {
|
|
147
|
-
applyDiscountCode(webManager);
|
|
135
|
+
if (name === 'billing-cycle') {
|
|
136
|
+
handleBillingCycleChange(value, webManager);
|
|
148
137
|
}
|
|
149
138
|
});
|
|
150
139
|
|
|
151
140
|
// Handle form submission
|
|
152
|
-
formManager.
|
|
153
|
-
event.preventDefault();
|
|
154
|
-
|
|
141
|
+
formManager.on('submit', async ({ $submitButton }) => {
|
|
155
142
|
// Get the submit button that was clicked
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
formManager.showError('Please choose a payment method.');
|
|
159
|
-
return;
|
|
143
|
+
if (!$submitButton) {
|
|
144
|
+
throw new Error('Please choose a payment method.');
|
|
160
145
|
}
|
|
161
146
|
|
|
162
147
|
// Check if a payment method was selected
|
|
163
|
-
const paymentMethod = submitButton.getAttribute('data-payment-method');
|
|
148
|
+
const paymentMethod = $submitButton.getAttribute('data-payment-method');
|
|
164
149
|
if (!paymentMethod) {
|
|
165
|
-
|
|
166
|
-
return;
|
|
150
|
+
throw new Error('Invalid payment method selected.');
|
|
167
151
|
}
|
|
168
152
|
|
|
169
153
|
// Set payment method in raw
|
|
@@ -181,6 +165,14 @@ function setupEventListeners() {
|
|
|
181
165
|
await completePurchase();
|
|
182
166
|
});
|
|
183
167
|
|
|
168
|
+
// Setup apply discount button (not part of form submit)
|
|
169
|
+
const $applyDiscountBtn = document.querySelector('[data-action="apply-discount"]');
|
|
170
|
+
if ($applyDiscountBtn) {
|
|
171
|
+
$applyDiscountBtn.addEventListener('click', () => {
|
|
172
|
+
applyDiscountCode(webManager);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
184
176
|
// Switch account link (keep as is - not part of form)
|
|
185
177
|
const $switchAccountLink = document.getElementById('switch-account');
|
|
186
178
|
if ($switchAccountLink) {
|
|
@@ -274,13 +266,8 @@ async function completePurchase() {
|
|
|
274
266
|
} catch (error) {
|
|
275
267
|
console.error('Purchase error:', error);
|
|
276
268
|
|
|
277
|
-
// FormManager
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
// Show user-friendly error message
|
|
281
|
-
const errorMessage = error.message || 'There was an error processing your payment. Please try again.';
|
|
282
|
-
|
|
283
|
-
formManager.showError(errorMessage);
|
|
269
|
+
// Re-throw to let FormManager handle error display and state restoration
|
|
270
|
+
throw error;
|
|
284
271
|
}
|
|
285
272
|
}
|
|
286
273
|
|
|
@@ -385,7 +372,7 @@ async function initializeCheckout() {
|
|
|
385
372
|
setupEventListeners();
|
|
386
373
|
|
|
387
374
|
// Set form to ready state
|
|
388
|
-
formManager.
|
|
375
|
+
formManager.ready();
|
|
389
376
|
|
|
390
377
|
// Track begin_checkout event on page load
|
|
391
378
|
const basePrice = raw.product.is_subscription
|
|
@@ -196,8 +196,9 @@ function trackPricingToggle(billingType) {
|
|
|
196
196
|
content_category: billingType
|
|
197
197
|
});
|
|
198
198
|
ttq.track('ViewContent', {
|
|
199
|
-
|
|
200
|
-
content_type:
|
|
199
|
+
content_id: 'pricing-page',
|
|
200
|
+
content_type: 'product',
|
|
201
|
+
content_name: 'Pricing Toggle'
|
|
201
202
|
});
|
|
202
203
|
}
|
|
203
204
|
|
|
@@ -247,6 +248,8 @@ function trackEnterpriseContact() {
|
|
|
247
248
|
content_name: 'Enterprise Plan'
|
|
248
249
|
});
|
|
249
250
|
ttq.track('Contact', {
|
|
251
|
+
content_id: 'enterprise-plan',
|
|
252
|
+
content_type: 'product',
|
|
250
253
|
content_name: 'Enterprise Plan'
|
|
251
254
|
});
|
|
252
255
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormManager Test Page JavaScript
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Libraries
|
|
6
|
+
import { FormManager } from '__main_assets__/js/libs/form-manager.js';
|
|
7
|
+
|
|
8
|
+
let webManager = null;
|
|
9
|
+
|
|
10
|
+
// Module
|
|
11
|
+
export default (Manager) => {
|
|
12
|
+
return new Promise(async function (resolve) {
|
|
13
|
+
// Shortcuts
|
|
14
|
+
webManager = Manager.webManager;
|
|
15
|
+
|
|
16
|
+
// Initialize when DOM is ready
|
|
17
|
+
await webManager.dom().ready();
|
|
18
|
+
|
|
19
|
+
// Initialize test forms
|
|
20
|
+
initTestFormMain();
|
|
21
|
+
initTestFormValidation();
|
|
22
|
+
initTestFormContact();
|
|
23
|
+
initTestFormManual();
|
|
24
|
+
|
|
25
|
+
// Resolve after initialization
|
|
26
|
+
return resolve();
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Helper: simulate async API call
|
|
31
|
+
function simulateApi(ms = 1000) {
|
|
32
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Test 1: Full Test (success/fail, nested, change events)
|
|
36
|
+
function initTestFormMain() {
|
|
37
|
+
const formManager = new FormManager('#test-form-main');
|
|
38
|
+
const $status = document.getElementById('main-status');
|
|
39
|
+
const $action = document.getElementById('main-action');
|
|
40
|
+
const $output = document.getElementById('main-output');
|
|
41
|
+
|
|
42
|
+
formManager.on('statechange', ({ state }) => {
|
|
43
|
+
$status.textContent = `Status: ${state}`;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
formManager.on('change', ({ name, value, data }) => {
|
|
47
|
+
console.log('[Test 1] Change:', name, '=', value);
|
|
48
|
+
console.log('[Test 1] Full data:', data);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
formManager.on('submit', async ({ data, $submitButton }) => {
|
|
52
|
+
console.log('[Test 1] Submitting:', data);
|
|
53
|
+
console.log('[Test 1] Submit button:', $submitButton?.dataset?.action);
|
|
54
|
+
|
|
55
|
+
// Show action separately
|
|
56
|
+
const action = $submitButton?.dataset?.action || 'unknown';
|
|
57
|
+
$action.textContent = `Action: ${action}`;
|
|
58
|
+
|
|
59
|
+
// Show data
|
|
60
|
+
$output.textContent = JSON.stringify(data, null, 2);
|
|
61
|
+
|
|
62
|
+
await simulateApi(1000);
|
|
63
|
+
|
|
64
|
+
if (data.settings.outcome === 'error') {
|
|
65
|
+
throw new Error('Simulated server error - please try again');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
formManager.showSuccess(`Form ${action === 'draft' ? 'saved as draft' : 'submitted'} successfully!`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Set Data button - test setData() API
|
|
72
|
+
const $setDataBtn = document.getElementById('main-set-data');
|
|
73
|
+
$setDataBtn.addEventListener('click', () => {
|
|
74
|
+
const testData = {
|
|
75
|
+
user: {
|
|
76
|
+
name: 'John Doe',
|
|
77
|
+
email: 'john@example.com',
|
|
78
|
+
address: {
|
|
79
|
+
city: 'Los Angeles',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
settings: {
|
|
83
|
+
outcome: 'error',
|
|
84
|
+
subscribe: true,
|
|
85
|
+
},
|
|
86
|
+
preferences: {
|
|
87
|
+
notifications: 'important',
|
|
88
|
+
features: {
|
|
89
|
+
darkmode: true,
|
|
90
|
+
analytics: true,
|
|
91
|
+
beta: false,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
formManager.setData(testData);
|
|
97
|
+
$output.textContent = 'Data set via setData() API - submit to verify';
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Test 2: Validation
|
|
102
|
+
function initTestFormValidation() {
|
|
103
|
+
const formManager = new FormManager('#test-form-validation');
|
|
104
|
+
const $status = document.getElementById('validation-status');
|
|
105
|
+
const $setCorrectBtn = document.getElementById('validation-set-correct');
|
|
106
|
+
|
|
107
|
+
formManager.on('statechange', ({ state }) => {
|
|
108
|
+
$status.textContent = `Status: ${state}`;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Validation event - runs BEFORE submit, use setError to accumulate errors
|
|
112
|
+
formManager.on('validation', ({ data, setError }) => {
|
|
113
|
+
console.log('[Test 2] Validating:', data);
|
|
114
|
+
|
|
115
|
+
// Custom validation (HTML5 validation handles required, email format, etc.)
|
|
116
|
+
// Here we add business logic validation
|
|
117
|
+
|
|
118
|
+
if (data.age && parseInt(data.age) < 18) {
|
|
119
|
+
setError('age', 'You must be 18 or older');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Note: 'required' validation is handled automatically by HTML5 validation
|
|
123
|
+
// We just need to add the 'required' attribute to the HTML inputs
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
formManager.on('submit', async ({ data }) => {
|
|
127
|
+
console.log('[Test 2] Submitting (validation passed):', data);
|
|
128
|
+
|
|
129
|
+
// If we reach here, validation passed
|
|
130
|
+
await simulateApi(500);
|
|
131
|
+
formManager.showSuccess('Validation passed! Form submitted.');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Set Correct button - fills in valid values
|
|
135
|
+
$setCorrectBtn.addEventListener('click', () => {
|
|
136
|
+
formManager.setData({
|
|
137
|
+
name: 'John Doe',
|
|
138
|
+
email: 'john@example.com',
|
|
139
|
+
age: 25,
|
|
140
|
+
terms: true,
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Test 3: Contact Form (one-time submit)
|
|
146
|
+
function initTestFormContact() {
|
|
147
|
+
const formManager = new FormManager('#test-form-contact', {
|
|
148
|
+
allowResubmit: false,
|
|
149
|
+
resetOnSuccess: true,
|
|
150
|
+
});
|
|
151
|
+
const $status = document.getElementById('contact-status');
|
|
152
|
+
|
|
153
|
+
formManager.on('statechange', ({ state }) => {
|
|
154
|
+
$status.textContent = `Status: ${state}`;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
formManager.on('change', ({ name, value, data }) => {
|
|
158
|
+
console.log('[Test 3] Change:', name, '=', value);
|
|
159
|
+
console.log('[Test 3] Full data:', data);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
formManager.on('submit', async ({ data }) => {
|
|
163
|
+
console.log('[Test 3] Submitting:', data);
|
|
164
|
+
await simulateApi(1000);
|
|
165
|
+
formManager.showSuccess('Message sent! Form is now locked.');
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Test 4: Manual Ready
|
|
170
|
+
function initTestFormManual() {
|
|
171
|
+
const formManager = new FormManager('#test-form-manual', { autoReady: false });
|
|
172
|
+
const $status = document.getElementById('manual-status');
|
|
173
|
+
|
|
174
|
+
formManager.on('statechange', ({ state }) => {
|
|
175
|
+
$status.textContent = `Status: ${state}`;
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
formManager.on('change', ({ name, value, data }) => {
|
|
179
|
+
console.log('[Test 4] Change:', name, '=', value);
|
|
180
|
+
console.log('[Test 4] Full data:', data);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
formManager.on('submit', async ({ data }) => {
|
|
184
|
+
console.log('[Test 4] Submitting:', data);
|
|
185
|
+
await simulateApi(1000);
|
|
186
|
+
formManager.showSuccess('Done!');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Simulate async initialization (e.g., loading user data)
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
console.log('[Test 4] Now ready');
|
|
192
|
+
formManager.ready();
|
|
193
|
+
}, 2000);
|
|
194
|
+
}
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
box-shadow: $classy-shadow-sm;
|
|
12
12
|
position: relative;
|
|
13
13
|
|
|
14
|
-
// Allow badges to overflow
|
|
15
|
-
&:has(.badge) {
|
|
14
|
+
// Allow badges to overflow (except when overflow-hidden is explicitly set)
|
|
15
|
+
&:has(.badge):not(.overflow-hidden) {
|
|
16
16
|
overflow: visible !important;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# ========== Default Values ==========
|
|
2
|
+
# macOS
|
|
1
3
|
.DS_Store
|
|
4
|
+
|
|
2
5
|
# Logs
|
|
3
6
|
logs
|
|
4
7
|
*.log
|
|
@@ -11,7 +14,6 @@ firebase-debug.log*
|
|
|
11
14
|
.firebase/
|
|
12
15
|
|
|
13
16
|
# Firebase config
|
|
14
|
-
|
|
15
17
|
# Uncomment this if you'd like others to create their own Firebase project.
|
|
16
18
|
# For a team working on the same Firebase project(s), it is recommended to leave
|
|
17
19
|
# it commented so all members can deploy to the same project(s) in .firebaserc.
|
|
@@ -77,3 +79,7 @@ node_modules/
|
|
|
77
79
|
/.cache
|
|
78
80
|
/_legacy
|
|
79
81
|
START-COMMANDS.md
|
|
82
|
+
|
|
83
|
+
# ========== Custom Values ==========
|
|
84
|
+
# Add your custom ignore patterns below this line
|
|
85
|
+
# ...
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
hidden>
|
|
10
10
|
<span class="main-alert-close">×</span>
|
|
11
11
|
<div>
|
|
12
|
-
|
|
12
|
+
{% uj_icon "warning", "fa-bounce me-2" %}
|
|
13
13
|
You are using an outdated browser that our site <strong>DOES NOT</strong> support. Please <a href="https://www.google.com/chrome" rel="nofollow" target="_blank">click here</a> to update your browser.
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
hidden>
|
|
20
20
|
<span class="main-alert-close">×</span>
|
|
21
21
|
<div>
|
|
22
|
-
|
|
22
|
+
{% uj_icon "warning", "fa-bounce me-2" %}
|
|
23
23
|
There is a <strong>problem with your payment method</strong>. To continue using <strong>{{ site.brand.name }}</strong>, please <a href="{{ site.url }}/account#billing" target="_blank">update your payment method</a>.
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
|
-
<div
|
|
26
|
+
<!-- <div
|
|
27
27
|
class="main-alert main-alert-top main-alert-fixed main-alert-sale bg-primary animation-fade-in"
|
|
28
28
|
role="alert" aria-live="polite" aria-label="Flash sale"
|
|
29
29
|
hidden>
|
|
@@ -33,17 +33,9 @@
|
|
|
33
33
|
<strong>FLASH SALE!</strong>
|
|
34
34
|
Save <strong>15%</strong> at checkout—today only! <a href="{{ site.url }}/pricing" target="_blank">Claim discount</a>.
|
|
35
35
|
</div>
|
|
36
|
-
</div>
|
|
36
|
+
</div> -->
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
Icon Pre-rendering System
|
|
40
|
-
Pages can specify which icons to pre-render in their frontmatter:
|
|
41
|
-
prerender_icons:
|
|
42
|
-
- name: "apple"
|
|
43
|
-
class: "fa-3xl"
|
|
44
|
-
- name: "android"
|
|
45
|
-
class: "fa-2xl"
|
|
46
|
-
{%- endcomment -%}
|
|
38
|
+
<!-- Prerendered Icons -->
|
|
47
39
|
{%- assign icons = page.resolved.prerender_icons | default: empty -%}
|
|
48
40
|
{%- iftruthy icons -%}
|
|
49
41
|
<!-- Pre-rendered Icon Templates -->
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
buildTime: {{ site.uj.cache_breaker }},
|
|
70
70
|
brand: {{ page.resolved.brand | jsonify }},
|
|
71
71
|
advertising: {{ page.resolved.advertising | jsonify }},
|
|
72
|
+
tracking: {{ page.resolved.tracking | jsonify }},
|
|
72
73
|
{% for item in page.resolved.web_manager %}
|
|
73
74
|
{{ item[0] | jsonify }}: {{ item[1] | jsonify }},
|
|
74
75
|
{% endfor %}
|
|
@@ -130,18 +130,23 @@
|
|
|
130
130
|
<span>{{ child.label }}</span>
|
|
131
131
|
</span>
|
|
132
132
|
{% endcapture %}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
133
|
+
|
|
134
|
+
{% if child.divider %}
|
|
135
|
+
<li><hr class="dropdown-divider" {{ child_attributes }}/></li>
|
|
136
|
+
{% else %}
|
|
137
|
+
<li>
|
|
138
|
+
{% iftruthy child.href %}
|
|
139
|
+
<a class="{{ child_class }}" href="{{ child.href }}" {{ child_attributes }}>
|
|
140
|
+
{{ child_content }}
|
|
141
|
+
</a>
|
|
142
|
+
{% endiftruthy %}
|
|
143
|
+
{% iffalsy child.href %}
|
|
144
|
+
<button class="{{ child_class }}" type="button" {{ child_attributes }}>
|
|
145
|
+
{{ child_content }}
|
|
146
|
+
</button>
|
|
147
|
+
{% endiffalsy %}
|
|
148
|
+
</li>
|
|
149
|
+
{% endif %}
|
|
145
150
|
{% endfor %}
|
|
146
151
|
</ul>
|
|
147
152
|
</li>
|
|
@@ -272,18 +277,23 @@
|
|
|
272
277
|
<span>{{ child.label }}</span>
|
|
273
278
|
</span>
|
|
274
279
|
{% endcapture %}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
280
|
+
|
|
281
|
+
{% if child.divider %}
|
|
282
|
+
<li><hr class="dropdown-divider" {{ child_attributes }}/></li>
|
|
283
|
+
{% else %}
|
|
284
|
+
<li>
|
|
285
|
+
{% iftruthy child.href %}
|
|
286
|
+
<a class="{{ child_class }}" href="{{ child.href }}" {{ child_attributes }}>
|
|
287
|
+
{{ child_content }}
|
|
288
|
+
</a>
|
|
289
|
+
{% endiftruthy %}
|
|
290
|
+
{% iffalsy child.href %}
|
|
291
|
+
<button class="{{ child_class }}" type="button" {{ child_attributes }}>
|
|
292
|
+
{{ child_content }}
|
|
293
|
+
</button>
|
|
294
|
+
{% endiffalsy %}
|
|
295
|
+
</li>
|
|
296
|
+
{% endif %}
|
|
287
297
|
{% endfor %}
|
|
288
298
|
</ul>
|
|
289
299
|
</div>
|
|
@@ -343,18 +353,23 @@
|
|
|
343
353
|
<span>{{ child.label }}</span>
|
|
344
354
|
</span>
|
|
345
355
|
{% endcapture %}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
|
|
357
|
+
{% if child.divider %}
|
|
358
|
+
<li><hr class="dropdown-divider" {{ child_attributes }}/></li>
|
|
359
|
+
{% else %}
|
|
360
|
+
<li>
|
|
361
|
+
{% iftruthy child.href %}
|
|
362
|
+
<a class="{{ child_class }}" href="{{ child.href }}" {{ child_attributes }}>
|
|
363
|
+
{{ child_content }}
|
|
364
|
+
</a>
|
|
365
|
+
{% endiftruthy %}
|
|
366
|
+
{% iffalsy child.href %}
|
|
367
|
+
<button class="{{ child_class }}" type="button" {{ child_attributes }}>
|
|
368
|
+
{{ child_content }}
|
|
369
|
+
</button>
|
|
370
|
+
{% endiffalsy %}
|
|
371
|
+
</li>
|
|
372
|
+
{% endif %}
|
|
358
373
|
{% endfor %}
|
|
359
374
|
</ul>
|
|
360
375
|
</div>
|
|
@@ -7,15 +7,26 @@ meta:
|
|
|
7
7
|
title: "Create Notification - Admin"
|
|
8
8
|
description: "Create and send a new notification"
|
|
9
9
|
breadcrumb: "Create Notification"
|
|
10
|
+
|
|
11
|
+
### ICON PRE-RENDERING ###
|
|
12
|
+
prerender_icons:
|
|
13
|
+
- name: "mobile"
|
|
14
|
+
class: "fa-sm me-1"
|
|
15
|
+
- name: "envelope"
|
|
16
|
+
class: "fa-sm me-1"
|
|
17
|
+
- name: "comment-sms"
|
|
18
|
+
class: "fa-sm me-1"
|
|
19
|
+
- name: "bell"
|
|
20
|
+
class: "fa-sm me-1"
|
|
10
21
|
---
|
|
11
22
|
|
|
12
23
|
<!-- Success/Error Alerts -->
|
|
13
24
|
<div class="notification-success-alert alert alert-success d-none" role="alert">
|
|
14
|
-
|
|
25
|
+
{% uj_icon "circle-check", "fa-sm" %} <span class="alert-message">Notification sent successfully!</span>
|
|
15
26
|
</div>
|
|
16
27
|
|
|
17
28
|
<div class="notification-error-alert alert alert-danger d-none" role="alert">
|
|
18
|
-
|
|
29
|
+
{% uj_icon "triangle-exclamation", "fa-sm" %} <span class="alert-message">An error occurred</span>
|
|
19
30
|
</div>
|
|
20
31
|
|
|
21
32
|
<!-- Notification Creation Form -->
|