PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.13
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.13
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 / learning-path / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.13, at blocks/learning-path/index.js

186 lines 14.9 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 PanelColorSettings = wp.blockEditor.PanelColorSettings;
5 var useBlockProps = wp.blockEditor.useBlockProps;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var TextControl = wp.components.TextControl;
8 var TextareaControl = wp.components.TextareaControl;
9 var ToggleControl = wp.components.ToggleControl;
10 var RangeControl = wp.components.RangeControl;
11 var SelectControl = wp.components.SelectControl;
12 var PanelBody = wp.components.PanelBody;
13 var Button = wp.components.Button;
14 var __ = wp.i18n.__;
15
16 var _tc, _tv;
17 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19
20 var typeOptions = [
21 { label: '📖 Lesson', value: 'lesson' },
22 { label: '🔨 Project', value: 'project' },
23 { label: '✏️ Quiz', value: 'quiz' },
24 { label: '📄 Reading', value: 'reading' },
25 { label: '🎬 Video', value: 'video' }
26 ];
27 var difficultyOptions = [
28 { label: 'Beginner', value: 'beginner' },
29 { label: 'Intermediate', value: 'intermediate' },
30 { label: 'Advanced', value: 'advanced' }
31 ];
32 var typeIcons = { lesson: '📖', project: '🔨', quiz: '✏️', reading: '📄', video: '🎬' };
33
34 function upd(arr, idx, field, val) {
35 return arr.map(function (e, i) {
36 if (i !== idx) return e;
37 var u = {}; u[field] = val;
38 return Object.assign({}, e, u);
39 });
40 }
41
42 function typeColor(t, a) {
43 var map = { lesson: a.lessonColor, project: a.projectColor, quiz: a.quizColor, reading: a.readingColor, video: a.videoColor };
44 return map[t] || a.lessonColor;
45 }
46
47 function renderStep(step, idx, total, a) {
48 var tc = typeColor(step.type, a);
49 return el('div', { className: 'bkbg-lp-step', key: idx },
50 el('div', { className: 'bkbg-lp-step-left' },
51 a.showStepNumbers && el('div', { className: 'bkbg-lp-step-num', style: { background: a.stepNumBg, color: a.stepNumColor } }, idx + 1),
52 idx < total - 1 && el('div', { className: 'bkbg-lp-connector', style: { background: a.connectorColor } })
53 ),
54 el('div', { className: 'bkbg-lp-step-card', style: { background: a.stepBg, border: '1px solid ' + a.stepBorderColor } },
55 el('div', { className: 'bkbg-lp-step-header' },
56 el('div', { className: 'bkbg-lp-step-title-row' },
57 el('span', { className: 'bkbg-lp-type-icon', style: { color: tc } }, typeIcons[step.type] || '📖'),
58 el('span', { className: 'bkbg-lp-step-title', style: { color: a.stepTitleColor } }, step.title)
59 ),
60 a.showDuration && step.duration && el('span', { className: 'bkbg-lp-duration', style: { color: a.durationColor } }, '' + step.duration)
61 ),
62 step.description && el('p', { className: 'bkbg-lp-step-desc', style: { color: a.stepDescColor } }, step.description),
63 a.showSkills && step.skills && step.skills.length > 0 &&
64 el('div', { className: 'bkbg-lp-skills' },
65 step.skills.map(function (s, j) {
66 return el('span', { key: j, className: 'bkbg-lp-skill-tag', style: { background: a.skillBg, color: a.skillColor } }, s);
67 })
68 )
69 )
70 );
71 }
72
73 wp.blocks.registerBlockType('blockenberg/learning-path', {
74 edit: function (props) {
75 var a = props.attributes;
76 var setAttr = props.setAttributes;
77 var lh = (a.lineHeight / 100).toFixed(2);
78
79 var difficultyLabels = { beginner: 'Beginner', intermediate: 'Intermediate', advanced: 'Advanced' };
80
81 var blockProps = useBlockProps((function () {
82 var _tvFn = getTypoCssVars();
83 var s = { background: a.bgColor, borderRadius: a.borderRadius + 'px', border: '1px solid ' + a.borderColor, overflow: 'hidden', fontSize: a.fontSize + 'px', lineHeight: lh };
84 if (_tvFn) {
85 Object.assign(s, _tvFn(a.titleTypo, '--bkbg-lp-tt-'));
86 Object.assign(s, _tvFn(a.descTypo, '--bkbg-lp-d-'));
87 Object.assign(s, _tvFn(a.stepTitleTypo, '--bkbg-lp-st-'));
88 }
89 return { className: 'bkbg-lp-wrap', style: s };
90 })());
91
92 return el(Fragment, null,
93 el(InspectorControls, null,
94 el(PanelBody, { title: __('Path Settings'), initialOpen: true },
95 el(TextControl, { label: __('Path Title'), value: a.pathTitle, onChange: function (v) { setAttr({ pathTitle: v }); }, __nextHasNoMarginBottom: true }),
96 el(TextareaControl, { label: __('Description'), value: a.description, onChange: function (v) { setAttr({ description: v }); }, __nextHasNoMarginBottom: true }),
97 el(ToggleControl, { label: __('Show Description'), checked: a.showDescription, onChange: function (v) { setAttr({ showDescription: v }); }, __nextHasNoMarginBottom: true }),
98 el(TextControl, { label: __('Total Duration'), value: a.totalDuration, onChange: function (v) { setAttr({ totalDuration: v }); }, __nextHasNoMarginBottom: true }),
99 el(SelectControl, { label: __('Difficulty'), value: a.difficulty, options: difficultyOptions, onChange: function (v) { setAttr({ difficulty: v }); }, __nextHasNoMarginBottom: true }),
100 el(ToggleControl, { label: __('Show Skills'), checked: a.showSkills, onChange: function (v) { setAttr({ showSkills: v }); }, __nextHasNoMarginBottom: true }),
101 el(ToggleControl, { label: __('Show Duration'), checked: a.showDuration, onChange: function (v) { setAttr({ showDuration: v }); }, __nextHasNoMarginBottom: true }),
102 el(ToggleControl, { label: __('Show Step Numbers'), checked: a.showStepNumbers, onChange: function (v) { setAttr({ showStepNumbers: v }); }, __nextHasNoMarginBottom: true })
103 ),
104 el(PanelBody, { title: __('Steps'), initialOpen: false },
105 a.steps.map(function (step, i) {
106 return el('div', { key: i, style: { border: '1px solid #e2e8f0', borderRadius: 8, padding: 12, marginBottom: 12, background: '#fafafa' } },
107 el('strong', { style: { display: 'block', marginBottom: 6 } }, (typeIcons[step.type] || '📖') + ' ' + (step.title || 'Step ' + (i + 1))),
108 el(TextControl, { label: __('Title'), value: step.title, onChange: function (v) { setAttr({ steps: upd(a.steps, i, 'title', v) }); }, __nextHasNoMarginBottom: true }),
109 el(TextareaControl, { label: __('Description'), value: step.description, onChange: function (v) { setAttr({ steps: upd(a.steps, i, 'description', v) }); }, __nextHasNoMarginBottom: true }),
110 el(SelectControl, { label: __('Type'), value: step.type, options: typeOptions, onChange: function (v) { setAttr({ steps: upd(a.steps, i, 'type', v) }); }, __nextHasNoMarginBottom: true }),
111 el(TextControl, { label: __('Duration'), value: step.duration, onChange: function (v) { setAttr({ steps: upd(a.steps, i, 'duration', v) }); }, __nextHasNoMarginBottom: true }),
112 el(TextControl, { label: __('Skills (comma-separated)'), value: (step.skills || []).join(', '), onChange: function (v) { setAttr({ steps: upd(a.steps, i, 'skills', v.split(',').map(function (s) { return s.trim(); }).filter(Boolean)) }); }, __nextHasNoMarginBottom: true }),
113 el(Button, { isDestructive: true, variant: 'secondary', onClick: function () { setAttr({ steps: a.steps.filter(function (_, j) { return j !== i; }) }); } }, __('Remove'))
114 );
115 }),
116 el(Button, { variant: 'primary', onClick: function () { setAttr({ steps: a.steps.concat([{ title: 'New Step', description: '', duration: '1 week', type: 'lesson', skills: [], completed: false }]) }); } }, __('+ Add Step'))
117 ),
118 el(PanelBody, { title: __('Typography'), initialOpen: false },
119 getTypoControl() && el(getTypoControl(), { label: __('Title'), value: a.titleTypo || {}, onChange: function (v) { setAttr({ titleTypo: v }); } }),
120 getTypoControl() && el(getTypoControl(), { label: __('Description'), value: a.descTypo || {}, onChange: function (v) { setAttr({ descTypo: v }); } }),
121 getTypoControl() && el(getTypoControl(), { label: __('Step Title'), value: a.stepTitleTypo || {}, onChange: function (v) { setAttr({ stepTitleTypo: v }); } }),
122 el(RangeControl, { label: __('Base Font Size'), value: a.fontSize, min: 10, max: 22, onChange: function (v) { setAttr({ fontSize: v }); }, __nextHasNoMarginBottom: true }),
123 el(RangeControl, { label: __('Line Height (%)'), value: a.lineHeight, min: 120, max: 220, onChange: function (v) { setAttr({ lineHeight: v }); }, __nextHasNoMarginBottom: true }),
124 el(RangeControl, { label: __('Border Radius'), value: a.borderRadius, min: 0, max: 32, onChange: function (v) { setAttr({ borderRadius: v }); }, __nextHasNoMarginBottom: true })
125 ),
126 el(PanelColorSettings, {
127 title: __('Layout Colors'),
128 initialOpen: false,
129 colorSettings: [
130 { label: __('Background'), value: a.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#ffffff' }); } },
131 { label: __('Border'), value: a.borderColor, onChange: function (v) { setAttr({ borderColor: v || '#e5e7eb' }); } },
132 { label: __('Title'), value: a.titleColor, onChange: function (v) { setAttr({ titleColor: v || '#111827' }); } },
133 { label: __('Description'), value: a.descColor, onChange: function (v) { setAttr({ descColor: v || '#6b7280' }); } },
134 { label: __('Meta Bar BG'), value: a.metaBg, onChange: function (v) { setAttr({ metaBg: v || '#f8fafc' }); } },
135 { label: __('Meta Bar Border'), value: a.metaBorderColor, onChange: function (v) { setAttr({ metaBorderColor: v || '#e2e8f0' }); } },
136 { label: __('Difficulty BG'), value: a.difficultyBg, onChange: function (v) { setAttr({ difficultyBg: v || '#ede9fe' }); } },
137 { label: __('Difficulty Text'), value: a.difficultyColor, onChange: function (v) { setAttr({ difficultyColor: v || '#5b21b6' }); } },
138 { label: __('Step Card BG'), value: a.stepBg, onChange: function (v) { setAttr({ stepBg: v || '#ffffff' }); } },
139 { label: __('Step Card Border'), value: a.stepBorderColor, onChange: function (v) { setAttr({ stepBorderColor: v || '#e5e7eb' }); } },
140 { label: __('Step Title'), value: a.stepTitleColor, onChange: function (v) { setAttr({ stepTitleColor: v || '#1f2937' }); } },
141 { label: __('Step Description'), value: a.stepDescColor, onChange: function (v) { setAttr({ stepDescColor: v || '#6b7280' }); } },
142 { label: __('Step Number BG'), value: a.stepNumBg, onChange: function (v) { setAttr({ stepNumBg: v || '#0f172a' }); } },
143 { label: __('Step Number Text'), value: a.stepNumColor, onChange: function (v) { setAttr({ stepNumColor: v || '#ffffff' }); } },
144 { label: __('Connector Line'), value: a.connectorColor, onChange: function (v) { setAttr({ connectorColor: v || '#e5e7eb' }); } },
145 { label: __('Duration Text'), value: a.durationColor, onChange: function (v) { setAttr({ durationColor: v || '#6b7280' }); } },
146 { label: __('Skill Tag BG'), value: a.skillBg, onChange: function (v) { setAttr({ skillBg: v || '#f1f5f9' }); } },
147 { label: __('Skill Tag Text'), value: a.skillColor, onChange: function (v) { setAttr({ skillColor: v || '#475569' }); } }
148 ]
149 }),
150 el(PanelColorSettings, {
151 title: __('Step Type Colors'),
152 initialOpen: false,
153 colorSettings: [
154 { label: __('📖 Lesson'), value: a.lessonColor, onChange: function (v) { setAttr({ lessonColor: v || '#2563eb' }); } },
155 { label: __('🔨 Project'), value: a.projectColor, onChange: function (v) { setAttr({ projectColor: v || '#d97706' }); } },
156 { label: __('✏️ Quiz'), value: a.quizColor, onChange: function (v) { setAttr({ quizColor: v || '#7c3aed' }); } },
157 { label: __('📄 Reading'), value: a.readingColor, onChange: function (v) { setAttr({ readingColor: v || '#059669' }); } },
158 { label: __('🎬 Video'), value: a.videoColor, onChange: function (v) { setAttr({ videoColor: v || '#dc2626' }); } }
159 ]
160 })
161 ),
162 el('div', blockProps,
163 el('div', { className: 'bkbg-lp-header', style: { borderBottom: '1px solid ' + a.borderColor } },
164 el('h2', { className: 'bkbg-lp-title', style: { color: a.titleColor } }, a.pathTitle),
165 a.showDescription && el('p', { className: 'bkbg-lp-desc', style: { color: a.descColor } }, a.description)
166 ),
167 el('div', { className: 'bkbg-lp-meta', style: { background: a.metaBg, borderBottom: '1px solid ' + a.metaBorderColor } },
168 el('span', { className: 'bkbg-lp-meta-item' }, '' + a.totalDuration),
169 el('span', { className: 'bkbg-lp-meta-item' }, '📚 ' + a.steps.length + ' steps'),
170 el('span', { className: 'bkbg-lp-difficulty', style: { background: a.difficultyBg, color: a.difficultyColor } }, { beginner: 'Beginner', intermediate: 'Intermediate', advanced: 'Advanced' }[a.difficulty] || a.difficulty)
171 ),
172 el('div', { className: 'bkbg-lp-steps' },
173 a.steps.map(function (step, i) { return renderStep(step, i, a.steps.length, a); })
174 )
175 )
176 );
177 },
178 save: function (props) {
179 var useBlockProps = wp.blockEditor.useBlockProps;
180 return el('div', useBlockProps.save(),
181 el('div', { className: 'bkbg-learning-path-app', 'data-opts': JSON.stringify(props.attributes) })
182 );
183 }
184 });
185 }() );
186