PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / course-curriculum / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/course-curriculum/index.js

360 lines 25.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var Fragment = wp.element.Fragment;
4 var useState = wp.element.useState;
5 var __ = wp.i18n.__;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var RichText = wp.blockEditor.RichText;
9 var useBlockProps = wp.blockEditor.useBlockProps;
10 var PanelBody = wp.components.PanelBody;
11 var Button = wp.components.Button;
12 var ToggleControl = wp.components.ToggleControl;
13 var RangeControl = wp.components.RangeControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16 var ColorPicker = wp.components.ColorPicker;
17 var Popover = wp.components.Popover;
18
19 var _ccrTC, _ccrTV;
20 function _tc() { return _ccrTC || (_ccrTC = window.bkbgTypographyControl); }
21 function _tv(obj, prefix) { var fn = _ccrTV || (_ccrTV = window.bkbgTypoCssVars); return fn ? fn(obj, prefix) : {}; }
22
23 var LESSON_TYPE_OPTIONS = [
24 { label: __('Video', 'blockenberg'), value: 'video' },
25 { label: __('Quiz', 'blockenberg'), value: 'quiz' },
26 { label: __('Exercise', 'blockenberg'), value: 'exercise' },
27 { label: __('Article', 'blockenberg'), value: 'article' },
28 ];
29
30 var LESSON_ICONS = { video: '', quiz: '📝', exercise: '💪', article: '📖' };
31
32 function makeId() { return 'cc' + Math.random().toString(36).substr(2, 5); }
33
34 function buildWrapStyle(a) {
35 return Object.assign({
36 '--bkbg-cc-accent': a.accentColor,
37 '--bkbg-cc-card-bg': a.cardBg,
38 '--bkbg-cc-card-border': a.cardBorder,
39 '--bkbg-cc-section-bg': a.sectionBg,
40 '--bkbg-cc-section-border': a.sectionBorder,
41 '--bkbg-cc-section-hover': a.sectionHoverBg,
42 '--bkbg-cc-lesson-bg': a.lessonBg,
43 '--bkbg-cc-lesson-hover': a.lessonHoverBg,
44 '--bkbg-cc-free-bg': a.freeBg,
45 '--bkbg-cc-free-color': a.freeColor,
46 '--bkbg-cc-locked-color': a.lockedColor,
47 '--bkbg-cc-title-color': a.titleColor,
48 '--bkbg-cc-sec-title-color': a.sectionTitleColor,
49 '--bkbg-cc-lesson-color': a.lessonTitleColor,
50 '--bkbg-cc-meta-color': a.metaColor,
51 '--bkbg-cc-btn-bg': a.btnBg,
52 '--bkbg-cc-btn-color': a.btnColor,
53 '--bkbg-cc-card-r': a.cardRadius + 'px',
54 '--bkbg-cc-sec-r': a.sectionRadius + 'px',
55 '--bkbg-cc-btn-r': a.btnRadius + 'px',
56 '--bkbg-cc-title-sz': a.titleSize + 'px',
57 '--bkbg-cc-sec-title-sz': a.sectionTitleSize + 'px',
58 '--bkbg-cc-lesson-sz': a.lessonTitleSize + 'px',
59 paddingTop: a.paddingTop + 'px',
60 paddingBottom: a.paddingBottom + 'px',
61 backgroundColor: a.bgColor || undefined,
62 }, _tv(a.typoTitle, '--bkbg-ccr-ttl-'), _tv(a.typoSection, '--bkbg-ccr-sec-'), _tv(a.typoLesson, '--bkbg-ccr-les-'));
63 }
64
65 function renderColorControl(key, label, value, onChange, openKey, setOpenKey) {
66 var isOpen = openKey === key;
67 return el('div', { key: key, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 0', gap: '8px' } },
68 el('span', { style: { fontSize: '12px', color: '#1e1e1e', flex: 1, lineHeight: 1.4 } }, label),
69 el('div', { style: { position: 'relative', flexShrink: 0 } },
70 el('button', { type: 'button', onClick: function () { setOpenKey(isOpen ? null : key); }, style: { width: '28px', height: '28px', borderRadius: '4px', border: isOpen ? '2px solid #007cba' : '2px solid #ddd', cursor: 'pointer', padding: 0, background: value || '#ccc' } }),
71 isOpen && el(Popover, { position: 'bottom left', onClose: function () { setOpenKey(null); } },
72 el('div', { style: { padding: '8px' } },
73 el(ColorPicker, { color: value, enableAlpha: true, onChange: onChange })
74 )
75 )
76 )
77 );
78 }
79
80 /* ── Lesson row in editor ────────────────────────────────────────── */
81 function LessonRow(props) {
82 var lesson = props.lesson;
83 var sectionId = props.sectionId;
84 var a = props.a;
85 var onUpdate = props.onUpdate;
86 var onRemove = props.onRemove;
87 var showEdit = props.showEdit;
88 var setShowEdit = props.setShowEdit;
89 var icon = LESSON_ICONS[lesson.type] || '';
90
91 return el('div', { className: 'bkbg-cc-lesson-row', style: { display: 'flex', alignItems: 'center', gap: '8px', padding: '7px 12px', borderBottom: '1px solid ' + a.cardBorder, background: a.lessonBg } },
92 el('span', { style: { fontSize: '14px', flexShrink: 0, minWidth: '20px' } }, icon),
93 el('input', { type: 'text', className: 'bkbg-cc-lesson-title', value: lesson.title, onChange: function (e) { onUpdate('title', e.target.value); },
94 placeholder: __('Lesson title…', 'blockenberg'),
95 style: { flex: 1, border: 'none', outline: 'none', color: a.lessonTitleColor, background: 'transparent', padding: 0 }
96 }),
97 el('select', { value: lesson.type, onChange: function (e) { onUpdate('type', e.target.value); }, style: { fontSize: '11px', border: '1px solid #ddd', borderRadius: '4px', background: '#fff', color: '#555', cursor: 'pointer', padding: '1px 4px', flexShrink: 0 } },
98 LESSON_TYPE_OPTIONS.map(function (opt) { return el('option', { key: opt.value, value: opt.value }, opt.label); })
99 ),
100 el('input', { type: 'text', value: lesson.duration, onChange: function (e) { onUpdate('duration', e.target.value); },
101 placeholder: '5:00',
102 style: { width: '46px', border: '1px solid #ddd', borderRadius: '4px', fontSize: '11px', color: '#555', textAlign: 'center', padding: '2px 4px', flexShrink: 0 }
103 }),
104 el('label', { style: { display: 'flex', alignItems: 'center', gap: '3px', fontSize: '11px', color: a.freeColor, cursor: 'pointer', flexShrink: 0 } },
105 el('input', { type: 'checkbox', checked: lesson.free, onChange: function (e) { onUpdate('free', e.target.checked); }, style: { accentColor: a.freeColor, width: '12px', height: '12px' } }),
106 __('Free', 'blockenberg')
107 ),
108 el('button', { type: 'button', onClick: onRemove, style: { border: 'none', background: 'none', cursor: 'pointer', color: '#ef4444', fontSize: '14px', padding: '0 2px', flexShrink: 0 } }, '×')
109 );
110 }
111
112 /* ── Section block in editor ─────────────────────────────────────── */
113 function SectionBlock(props) {
114 var section = props.section;
115 var a = props.a;
116 var isOpen = props.isOpen;
117 var onToggle = props.onToggle;
118 var onUpdateSection = props.onUpdateSection;
119 var onRemoveSection = props.onRemoveSection;
120 var onAddLesson = props.onAddLesson;
121 var onUpdateLesson = props.onUpdateLesson;
122 var onRemoveLesson = props.onRemoveLesson;
123 var editLessonState = useState(null);
124 var setEditLesson = editLessonState[1];
125 var showEditLesson = editLessonState[0];
126
127 return el('div', { className: 'bkbg-cc-section', style: { border: '1px solid ' + a.sectionBorder, borderRadius: a.sectionRadius + 'px', marginBottom: '8px', overflow: 'hidden' } },
128 /* Section header row */
129 el('div', { className: isOpen ? 'bkbg-cc-sec-hdr is-open' : 'bkbg-cc-sec-hdr', style: { display: 'flex', alignItems: 'center', gap: '10px', padding: '12px 14px', background: a.sectionBg, cursor: 'pointer' } },
130 el('span', { style: { fontSize: '14px', transform: isOpen ? 'rotate(90deg)' : 'none', transition: 'transform 0.2s', flexShrink: 0, color: a.accentColor } }, ''),
131 el('input', { type: 'text', className: 'bkbg-cc-sec-title', value: section.title, onChange: function (e) { onUpdateSection('title', e.target.value); },
132 onClick: function (e) { e.stopPropagation(); },
133 placeholder: __('Section title…', 'blockenberg'),
134 style: { flex: 1, border: 'none', outline: 'none', background: 'transparent', color: a.sectionTitleColor }
135 }),
136 el('span', { style: { fontSize: '12px', color: a.metaColor, flexShrink: 0 } }, section.lessons.length + ' ' + (section.lessons.length === 1 ? __('lesson', 'blockenberg') : __('lessons', 'blockenberg'))),
137 el('button', { type: 'button', onClick: function (e) { e.stopPropagation(); onRemoveSection(); }, style: { border: 'none', background: 'none', cursor: 'pointer', color: '#ef4444', fontSize: '16px', padding: '0 2px', flexShrink: 0 } }, '×'),
138 /* toggle icon */
139 el('div', { onClick: function () { onToggle(); }, style: { position: 'absolute', inset: 0 } })
140 ),
141 /* Lessons */
142 isOpen && el('div', { className: 'bkbg-cc-sec-body' },
143 section.lessons.map(function (lesson) {
144 return el(LessonRow, { key: lesson.id, lesson: lesson, sectionId: section.id, a: a,
145 showEdit: showEditLesson === lesson.id,
146 setShowEdit: setEditLesson,
147 onUpdate: function (key, val) { onUpdateLesson(lesson.id, key, val); },
148 onRemove: function () { onRemoveLesson(lesson.id); }
149 });
150 }),
151 el('button', { type: 'button', onClick: onAddLesson, style: { display: 'block', width: '100%', padding: '8px', background: 'none', border: 'none', borderTop: '1px solid ' + a.cardBorder, cursor: 'pointer', fontSize: '12px', color: a.accentColor, fontWeight: 700, textAlign: 'center' } },
152 '+ ' + __('Add Lesson', 'blockenberg')
153 )
154 )
155 );
156 }
157
158 registerBlockType('blockenberg/course-curriculum', {
159 title: __('Course Curriculum', 'blockenberg'),
160 icon: 'welcome-learn-more',
161 category: 'bkbg-blog',
162
163 edit: function (props) {
164 var a = props.attributes;
165 var setAttributes = props.setAttributes;
166
167 var openColorKeyState = useState(null);
168 var openColorKey = openColorKeyState[0];
169 var setOpenColorKey = openColorKeyState[1];
170
171 var openSectionState = useState(0);
172 var openSection = openSectionState[0];
173 var setOpenSection = openSectionState[1];
174
175 var blockProps = useBlockProps({ style: buildWrapStyle(a) });
176
177 function cc(key, label, attrKey) {
178 return renderColorControl(key, label, a[attrKey], function (val) {
179 var upd = {}; upd[attrKey] = val; setAttributes(upd);
180 }, openColorKey, setOpenColorKey);
181 }
182
183 function updateSection(sectionId, key, val) {
184 setAttributes({ sections: a.sections.map(function (s) {
185 if (s.id !== sectionId) return s;
186 var u = Object.assign({}, s); u[key] = val; return u;
187 }) });
188 }
189
190 function addSection() {
191 var newId = makeId();
192 setAttributes({ sections: a.sections.concat([{
193 id: newId,
194 title: __('New Section', 'blockenberg'),
195 lessons: []
196 }]) });
197 setOpenSection(a.sections.length); /* open the new one */
198 }
199
200 function removeSection(sectionId) {
201 setAttributes({ sections: a.sections.filter(function (s) { return s.id !== sectionId; }) });
202 }
203
204 function addLesson(sectionId) {
205 setAttributes({ sections: a.sections.map(function (s) {
206 if (s.id !== sectionId) return s;
207 return Object.assign({}, s, { lessons: s.lessons.concat([{ id: makeId(), title: __('New Lesson', 'blockenberg'), duration: '5:00', type: 'video', free: false }]) });
208 }) });
209 }
210
211 function updateLesson(sectionId, lessonId, key, val) {
212 setAttributes({ sections: a.sections.map(function (s) {
213 if (s.id !== sectionId) return s;
214 return Object.assign({}, s, { lessons: s.lessons.map(function (l) {
215 if (l.id !== lessonId) return l;
216 var u = Object.assign({}, l); u[key] = val; return u;
217 }) });
218 }) });
219 }
220
221 function removeLesson(sectionId, lessonId) {
222 setAttributes({ sections: a.sections.map(function (s) {
223 if (s.id !== sectionId) return s;
224 return Object.assign({}, s, { lessons: s.lessons.filter(function (l) { return l.id !== lessonId; }) });
225 }) });
226 }
227
228 var totalLessons = a.sections.reduce(function (sum, s) { return sum + s.lessons.length; }, 0);
229
230 return el(Fragment, null,
231 el(InspectorControls, null,
232 el(PanelBody, { title: __('Course Info', 'blockenberg'), initialOpen: true },
233 el(TextControl, { label: __('Course meta line', 'blockenberg'), value: a.courseMeta, onChange: function (v) { setAttributes({ courseMeta: v }); }, help: __('e.g. "12 sections • 48 lessons • 24h"', 'blockenberg') }),
234 el(ToggleControl, { label: __('Show course meta', 'blockenberg'), checked: a.showCourseMeta, onChange: function (v) { setAttributes({ showCourseMeta: v }); }, __nextHasNoMarginBottom: true }),
235 el(ToggleControl, { label: __('Show search bar', 'blockenberg'), checked: a.showSearch, onChange: function (v) { setAttributes({ showSearch: v }); }, __nextHasNoMarginBottom: true }),
236 el(ToggleControl, { label: __('Expand all by default', 'blockenberg'), checked: a.expandAll, onChange: function (v) { setAttributes({ expandAll: v }); }, __nextHasNoMarginBottom: true }),
237 !a.expandAll && el(RangeControl, { label: __('Default open section (0 = first)', 'blockenberg'), value: a.defaultOpen, min: 0, max: Math.max(0, a.sections.length - 1), onChange: function (v) { setAttributes({ defaultOpen: v }); } })
238 ),
239 el(PanelBody, { title: __('CTA Button', 'blockenberg'), initialOpen: false },
240 el(ToggleControl, { label: __('Show CTA button', 'blockenberg'), checked: a.showCta, onChange: function (v) { setAttributes({ showCta: v }); }, __nextHasNoMarginBottom: true }),
241 a.showCta && el(TextControl, { label: __('Button label', 'blockenberg'), value: a.ctaLabel, onChange: function (v) { setAttributes({ ctaLabel: v }); } }),
242 a.showCta && el(TextControl, { label: __('Button URL', 'blockenberg'), value: a.ctaUrl, onChange: function (v) { setAttributes({ ctaUrl: v }); } })
243 ),
244 el(PanelBody, { title: __('Sizing', 'blockenberg'), initialOpen: false },
245 el(RangeControl, { label: __('Card radius (px)', 'blockenberg'), value: a.cardRadius, min: 0, max: 32, onChange: function (v) { setAttributes({ cardRadius: v }); } }),
246 el(RangeControl, { label: __('Section radius (px)', 'blockenberg'), value: a.sectionRadius, min: 0, max: 20, onChange: function (v) { setAttributes({ sectionRadius: v }); } }),
247 el(RangeControl, { label: __('Button radius (px)', 'blockenberg'), value: a.btnRadius, min: 0, max: 99, onChange: function (v) { setAttributes({ btnRadius: v }); } }),
248 ),
249
250 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
251 _tc() && el(_tc(), { label: __('Course Title', 'blockenberg'), value: a.typoTitle, onChange: function (v) { setAttributes({ typoTitle: v }); } }),
252 _tc() && el(_tc(), { label: __('Section Title', 'blockenberg'), value: a.typoSection, onChange: function (v) { setAttributes({ typoSection: v }); } }),
253 _tc() && el(_tc(), { label: __('Lesson Title', 'blockenberg'), value: a.typoLesson, onChange: function (v) { setAttributes({ typoLesson: v }); } })
254 ),
255 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
256 cc('accentColor', __('Accent', 'blockenberg'), 'accentColor'),
257 cc('titleColor', __('Course title', 'blockenberg'), 'titleColor'),
258 cc('sectionTitleColor', __('Section title', 'blockenberg'), 'sectionTitleColor'),
259 cc('lessonTitleColor', __('Lesson text', 'blockenberg'), 'lessonTitleColor'),
260 cc('metaColor', __('Meta / count', 'blockenberg'), 'metaColor'),
261 cc('cardBg', __('Card bg', 'blockenberg'), 'cardBg'),
262 cc('cardBorder', __('Card border', 'blockenberg'), 'cardBorder'),
263 cc('sectionBg', __('Section header bg','blockenberg'), 'sectionBg'),
264 cc('sectionBorder', __('Section border', 'blockenberg'), 'sectionBorder'),
265 cc('sectionHoverBg', __('Section hover', 'blockenberg'), 'sectionHoverBg'),
266 cc('lessonBg', __('Lesson row bg', 'blockenberg'), 'lessonBg'),
267 cc('lessonHoverBg', __('Lesson hover', 'blockenberg'), 'lessonHoverBg'),
268 cc('freeBg', __('Free badge bg', 'blockenberg'), 'freeBg'),
269 cc('freeColor', __('Free badge text', 'blockenberg'), 'freeColor'),
270 cc('lockedColor', __('Locked icon', 'blockenberg'), 'lockedColor'),
271 cc('btnBg', __('Button bg', 'blockenberg'), 'btnBg'),
272 cc('btnColor', __('Button text', 'blockenberg'), 'btnColor'),
273 cc('bgColor', __('Section bg', 'blockenberg'), 'bgColor')
274 ),
275 el(PanelBody, { title: __('Spacing', 'blockenberg'), initialOpen: false },
276 el(RangeControl, { label: __('Padding top', 'blockenberg'), value: a.paddingTop, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingTop: v }); } }),
277 el(RangeControl, { label: __('Padding bottom', 'blockenberg'), value: a.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingBottom: v }); } })
278 )
279 ),
280
281 el('div', blockProps,
282 /* Card */
283 el('div', { className: 'bkbg-cc-card', style: { background: a.cardBg, border: '1px solid ' + a.cardBorder, borderRadius: a.cardRadius + 'px', overflow: 'hidden' } },
284 /* Card header */
285 el('div', { className: 'bkbg-cc-card-hdr', style: { padding: '24px 28px', borderBottom: '1px solid ' + a.cardBorder } },
286 el(RichText, { tagName: 'h2', className: 'bkbg-cc-course-title', value: a.courseTitle, onChange: function (v) { setAttributes({ courseTitle: v }); }, placeholder: __('Course title…', 'blockenberg'), style: { color: a.titleColor, margin: '0 0 6px' } }),
287 a.showCourseMeta && el('p', { className: 'bkbg-cc-course-meta', style: { fontSize: '13px', color: a.metaColor, margin: 0 } }, a.courseMeta || (a.sections.length + ' sections • ' + totalLessons + ' lessons'))
288 ),
289 /* Sections */
290 el('div', { className: 'bkbg-cc-sections-list', style: { padding: '16px 20px' } },
291 a.sections.map(function (section, idx) {
292 return el(SectionBlock, { key: section.id, section: section, a: a,
293 isOpen: openSection === idx,
294 onToggle: function () { setOpenSection(openSection === idx ? -1 : idx); },
295 onUpdateSection: function (key, val) { updateSection(section.id, key, val); },
296 onRemoveSection: function () { removeSection(section.id); },
297 onAddLesson: function () { addLesson(section.id); },
298 onUpdateLesson: function (lid, key, val) { updateLesson(section.id, lid, key, val); },
299 onRemoveLesson: function (lid) { removeLesson(section.id, lid); }
300 });
301 }),
302 el(Button, { variant: 'secondary', onClick: addSection, style: { width: '100%', justifyContent: 'center', marginTop: '8px' } }, '+ ' + __('Add Section', 'blockenberg'))
303 ),
304 /* CTA */
305 a.showCta && el('div', { className: 'bkbg-cc-cta-wrap', style: { padding: '20px 28px', borderTop: '1px solid ' + a.cardBorder, textAlign: 'center' } },
306 el('a', { href: a.ctaUrl, className: 'bkbg-cc-cta-btn', style: { display: 'inline-block', padding: '14px 36px', borderRadius: a.btnRadius + 'px', background: a.btnBg, color: a.btnColor, fontWeight: 800, fontSize: '16px', textDecoration: 'none' } }, a.ctaLabel)
307 )
308 )
309 )
310 );
311 },
312
313 save: function (props) {
314 var a = props.attributes;
315 var totalLessons = a.sections.reduce(function (sum, s) { return sum + s.lessons.length; }, 0);
316
317 return el('div', wp.blockEditor.useBlockProps.save({ className: 'bkbg-cc-wrapper', style: buildWrapStyle(a) }),
318 el('div', { className: 'bkbg-cc-card', 'data-expand-all': a.expandAll ? '1' : '0', 'data-default-open': a.defaultOpen },
319 el('div', { className: 'bkbg-cc-card-hdr' },
320 el(RichText.Content, { tagName: 'h2', className: 'bkbg-cc-course-title', value: a.courseTitle }),
321 a.showCourseMeta && el('p', { className: 'bkbg-cc-course-meta' }, a.courseMeta || (a.sections.length + ' sections • ' + totalLessons + ' lessons'))
322 ),
323 el('div', { className: 'bkbg-cc-sections-list' },
324 a.sections.map(function (section, idx) {
325 var videoCount = section.lessons.filter(function (l) { return l.type === 'video'; }).length;
326 return el('div', { key: section.id, className: 'bkbg-cc-section', 'data-section-idx': idx },
327 el('button', { type: 'button', className: 'bkbg-cc-sec-hdr', 'aria-expanded': a.expandAll || a.defaultOpen === idx ? 'true' : 'false' },
328 el('span', { className: 'bkbg-cc-sec-arrow', 'aria-hidden': 'true' }, ''),
329 el('span', { className: 'bkbg-cc-sec-title' }, section.title),
330 el('span', { className: 'bkbg-cc-sec-meta' }, section.lessons.length + ' ' + __('lessons', 'blockenberg') + (videoCount ? '' + videoCount + ' ' + __('videos', 'blockenberg') : ''))
331 ),
332 el('div', { className: 'bkbg-cc-lessons', 'aria-hidden': a.expandAll || a.defaultOpen === idx ? 'false' : 'true' },
333 section.lessons.map(function (lesson) {
334 var icon = LESSON_ICONS[lesson.type] || '';
335 return el('div', { key: lesson.id, className: 'bkbg-cc-lesson ' + (lesson.free ? 'is-free' : 'is-locked'), 'data-type': lesson.type },
336 el('div', { className: 'bkbg-cc-lesson-left' },
337 el('span', { className: 'bkbg-cc-lesson-icon', 'aria-hidden': 'true' }, icon),
338 el('span', { className: 'bkbg-cc-lesson-title' }, lesson.title)
339 ),
340 el('div', { className: 'bkbg-cc-lesson-right' },
341 lesson.free
342 ? el('span', { className: 'bkbg-cc-free-badge' }, __('Free', 'blockenberg'))
343 : el('span', { className: 'bkbg-cc-locked-icon', 'aria-label': __('Locked', 'blockenberg') }, '🔒'),
344 lesson.duration && el('span', { className: 'bkbg-cc-lesson-dur' }, lesson.duration)
345 )
346 );
347 })
348 )
349 );
350 })
351 ),
352 a.showCta && el('div', { className: 'bkbg-cc-cta-wrap' },
353 el('a', { href: a.ctaUrl, className: 'bkbg-cc-cta-btn' }, a.ctaLabel)
354 )
355 )
356 );
357 }
358 });
359 }() );
360