PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / tutorial-card / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/tutorial-card/frontend.js

234 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 function mk(tag, cls, styles) {
5 var d = document.createElement(tag);
6 if (cls) d.className = cls;
7 if (styles) Object.keys(styles).forEach(function (k) { d.style[k] = styles[k]; });
8 return d;
9 }
10 function tx(tag, cls, text, styles) {
11 var d = mk(tag, cls, styles);
12 d.textContent = text;
13 return d;
14 }
15 function ap(parent) {
16 Array.prototype.slice.call(arguments, 1).forEach(function (c) { if (c) parent.appendChild(c); });
17 return parent;
18 }
19
20 function difficultyInfo(d) {
21 if (d === 'beginner') return { label: '🟢 Beginner', bg: '#dcfce7', color: '#14532d' };
22 if (d === 'advanced') return { label: '🔴 Advanced', bg: '#fee2e2', color: '#991b1b' };
23 return { label: '🟡 Intermediate', bg: '#fef9c3', color: '#854d0e' };
24 }
25
26 function sectionHead(labelText, accentColor, borderColor, parentEl) {
27 var wrap = mk('div', 'bkbg-tc-section-head');
28 var label = tx('span', 'bkbg-tc-section-label', labelText, { color: accentColor });
29 var rule = mk('div', 'bkbg-tc-section-rule', { background: borderColor });
30 ap(wrap, label, rule);
31 ap(parentEl, wrap);
32 }
33
34 function init() {
35 document.querySelectorAll('.bkbg-tutorial-card-app').forEach(function (appEl) {
36 if (appEl.dataset.rendered) return;
37 appEl.dataset.rendered = '1';
38
39 var opts;
40 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
41
42 var o = Object.assign({
43 tutorialTitle: 'Tutorial', subtitle: '', author: '', showAuthor: true,
44 difficulty: 'intermediate', duration: '', showDuration: true,
45 completionRate: 0, showProgress: false,
46 prerequisites: [], showPrerequisites: true, prerequisitesLabel: 'Prerequisites',
47 steps: [], showSteps: true, stepsLabel: 'Steps',
48 showStepDurations: true, showTips: true,
49 materials: [], showMaterials: true, materialsLabel: "What you'll need",
50 outcomes: [], showOutcomes: true, outcomesLabel: "What you'll learn",
51 fontSize: 14, titleFontSize: 22, lineHeight: 168, borderRadius: 12,
52 bgColor: '#ffffff', borderColor: '#e5e7eb',
53 headerBg: '#0f172a', headerColor: '#ffffff',
54 accentColor: '#3b82f6',
55 stepNumberBg: '#3b82f6', stepNumberColor: '#ffffff',
56 stepBorderColor: '#e5e7eb',
57 stepTipBg: '#fffbeb', stepTipColor: '#92400e', stepTipBorderColor: '#fcd34d',
58 prerequisiteBg: '#f1f5f9', prerequisiteColor: '#334155',
59 materialBg: '#f0f9ff', materialColor: '#0c4a6e',
60 outcomeBg: '#f0fdf4', outcomeColor: '#14532d',
61 progressBg: '#e5e7eb', progressFill: '#3b82f6'
62 }, opts);
63
64 var lh = (o.lineHeight / 100).toFixed(2);
65
66 // ── Block wrapper ─────────────────────────────────────
67 var block = mk('div', 'bkbg-tc-block', {
68 border: '1px solid ' + o.borderColor,
69 borderRadius: o.borderRadius + 'px',
70 overflow: 'hidden',
71 background: o.bgColor
72 });
73
74 // ── Header ───────────────────────────────────────────
75 var header = mk('div', 'bkbg-tc-header', { background: o.headerBg });
76
77 // Meta row: difficulty + duration + author
78 var diff = difficultyInfo(o.difficulty);
79 var metaRow = mk('div', 'bkbg-tc-meta-row');
80 ap(metaRow, tx('span', 'bkbg-tc-difficulty', diff.label, { background: diff.bg, color: diff.color }));
81 if (o.showDuration && o.duration) {
82 ap(metaRow, tx('span', 'bkbg-tc-meta-item', '' + o.duration, { color: o.headerColor }));
83 }
84 if (o.showAuthor && o.author) {
85 ap(metaRow, tx('span', 'bkbg-tc-meta-item', '✍️ ' + o.author, { color: o.headerColor }));
86 }
87 ap(header, metaRow);
88
89 // Title
90 ap(header, tx('h2', 'bkbg-tc-title', o.tutorialTitle, {
91 color: o.headerColor
92 }));
93
94 // Subtitle
95 if (o.subtitle) {
96 ap(header, tx('p', 'bkbg-tc-subtitle', o.subtitle, {
97 color: o.headerColor
98 }));
99 }
100
101 // Progress bar
102 if (o.showProgress) {
103 var progWrap = mk('div', 'bkbg-tc-progress-wrap');
104 var progLbl = mk('div', 'bkbg-tc-progress-label');
105 ap(progLbl,
106 tx('span', '', 'Progress', { color: o.headerColor }),
107 tx('span', '', o.completionRate + '%', { color: o.headerColor })
108 );
109 var track = mk('div', 'bkbg-tc-progress-track', { background: 'rgba(255,255,255,.2)' });
110 var fill = mk('div', 'bkbg-tc-progress-fill', { background: o.progressFill, width: o.completionRate + '%' });
111 ap(track, fill);
112 ap(progWrap, progLbl, track);
113 ap(header, progWrap);
114 }
115 ap(block, header);
116
117 // ── Body ─────────────────────────────────────────────
118 var body = mk('div', 'bkbg-tc-body');
119
120 // Outcomes
121 if (o.showOutcomes && o.outcomes && o.outcomes.length > 0) {
122 sectionHead(o.outcomesLabel || "What you'll learn", o.accentColor, o.borderColor, body);
123 var outcomeList = mk('ul', 'bkbg-tc-outcomes');
124 o.outcomes.forEach(function (item) {
125 if (!item || !item.text) return;
126 var li = mk('li', 'bkbg-tc-outcome');
127 var icon = tx('span', 'bkbg-tc-outcome-icon', '', { background: o.outcomeBg, color: o.outcomeColor });
128 var txt = tx('span', 'bkbg-tc-body-text', item.text, { color: '#374151' });
129 ap(li, icon, txt);
130 ap(outcomeList, li);
131 });
132 ap(body, outcomeList);
133 }
134
135 // Prerequisites & Materials — two column row
136 var hasPre = o.showPrerequisites && o.prerequisites && o.prerequisites.length > 0;
137 var hasMat = o.showMaterials && o.materials && o.materials.length > 0;
138 if (hasPre || hasMat) {
139 var cols = mk('div', 'bkbg-tc-meta-cols');
140 if (hasPre) {
141 var preCol = mk('div', 'bkbg-tc-col');
142 sectionHead(o.prerequisitesLabel || 'Prerequisites', o.accentColor, o.borderColor, preCol);
143 var preList = mk('ul', 'bkbg-tc-list');
144 o.prerequisites.forEach(function (item) {
145 if (!item || !item.text) return;
146 ap(preList, tx('li', 'bkbg-tc-list-item', '' + item.text, {
147 background: o.prerequisiteBg,
148 color: o.prerequisiteColor
149 }));
150 });
151 ap(preCol, preList);
152 ap(cols, preCol);
153 }
154 if (hasMat) {
155 var matCol = mk('div', 'bkbg-tc-col');
156 sectionHead(o.materialsLabel || "What you'll need", o.accentColor, o.borderColor, matCol);
157 var matList = mk('ul', 'bkbg-tc-list');
158 o.materials.forEach(function (item) {
159 if (!item || !item.text) return;
160 ap(matList, tx('li', 'bkbg-tc-list-item', '' + item.text, {
161 background: o.materialBg,
162 color: o.materialColor
163 }));
164 });
165 ap(matCol, matList);
166 ap(cols, matCol);
167 }
168 ap(body, cols);
169 }
170
171 // Steps
172 if (o.showSteps && o.steps && o.steps.length > 0) {
173 sectionHead(o.stepsLabel || 'Steps', o.accentColor, o.borderColor, body);
174 var stepList = mk('ol', 'bkbg-tc-steps');
175
176 o.steps.forEach(function (step, i) {
177 var li = mk('li', 'bkbg-tc-step');
178 var isLast = i === o.steps.length - 1;
179 if (!isLast) {
180 li.style.borderBottom = '1px solid ' + o.stepBorderColor;
181 }
182
183 // Number circle
184 var numCircle = tx('div', 'bkbg-tc-step-num', String(i + 1), {
185 background: o.stepNumberBg,
186 color: o.stepNumberColor
187 });
188
189 // Step body
190 var stepBody = mk('div', 'bkbg-tc-step-body');
191
192 // Title row
193 var titleRow = mk('div', 'bkbg-tc-step-title-row');
194 ap(titleRow, tx('span', 'bkbg-tc-step-title', step.title || ('Step ' + (i + 1))));
195 if (o.showStepDurations && step.duration) {
196 ap(titleRow, tx('span', 'bkbg-tc-step-duration', '' + step.duration));
197 }
198 ap(stepBody, titleRow);
199
200 // Content
201 ap(stepBody, tx('p', 'bkbg-tc-step-content', step.content || '', {
202 color: '#374151'
203 }));
204
205 // Tip
206 if (o.showTips && step.tip) {
207 var tip = mk('div', 'bkbg-tc-tip', {
208 background: o.stepTipBg,
209 color: o.stepTipColor,
210 borderLeftColor: o.stepTipBorderColor
211 });
212 var tipStrong = document.createElement('strong');
213 tipStrong.textContent = '💡 Tip: ';
214 tip.appendChild(tipStrong);
215 tip.appendChild(document.createTextNode(step.tip));
216 ap(stepBody, tip);
217 }
218
219 ap(li, numCircle, stepBody);
220 ap(stepList, li);
221 });
222 ap(body, stepList);
223 }
224
225 ap(block, body);
226 appEl.parentNode.insertBefore(block, appEl);
227 appEl.style.display = 'none';
228 });
229 }
230
231 if (document.readyState !== 'loading') { init(); }
232 else { document.addEventListener('DOMContentLoaded', init); }
233 })();
234