PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.14
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.14
2.0.14 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 / trivia-game / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.14, at blocks/trivia-game/index.js

155 lines 9.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 registerBlockType = wp.blocks.registerBlockType;
5 var __ = wp.i18n.__;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelBody = wp.components.PanelBody;
11 var RangeControl = wp.components.RangeControl;
12 var ToggleControl = wp.components.ToggleControl;
13 var SelectControl = wp.components.SelectControl;
14
15 // Resolve the shared components lazily without defining globals for each block.
16 function _tc(props, key, label) {
17 var Control = window.bkbgTypographyControl;
18 return Control ? el(Control, {
19 label: label,
20 value: props.attributes[key] || {},
21 onChange: function (value) { var update = {}; update[key] = value; props.setAttributes(update); }
22 }) : null;
23 }
24 function _tvf(typo, prefix) {
25 var cssVars = window.bkbgTypoCssVars;
26 return cssVars ? cssVars(typo || {}, prefix) : {};
27 }
28 function getTypoControl(props, attrName, label) { return _tc(props, attrName, label); }
29
30 var CATEGORIES = [
31 { label: 'Mixed (all)', value: 'mixed' },
32 { label: 'Science & Nature', value: 'science' },
33 { label: 'History', value: 'history' },
34 { label: 'Geography', value: 'geography' },
35 { label: 'Pop Culture & Entertainment', value: 'popculture' },
36 { label: 'Sports', value: 'sports' },
37 { label: 'Technology', value: 'technology' }
38 ];
39
40 var DEMO_Q = 'How many bones are in the adult human body?';
41 var DEMO_A = ['206', '187', '215', '232'];
42
43 function EditorPreview(props) {
44 var a = props.attributes;
45 var setAttributes = props.setAttributes;
46 var blockProps = (function () {
47 var s = { background: a.sectionBg || '#f0f4ff', padding: '28px 20px' };
48 Object.assign(s, _tvf(a.titleTypo, '--bktrv-tt-'), _tvf(a.subtitleTypo, '--bktrv-st-'));
49 return useBlockProps({ style: s });
50 })();
51
52 return el(Fragment, null,
53 el(InspectorControls, null,
54 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
55 ),
56 el(PanelBody, { title: __('Game Settings', 'blockenberg'), initialOpen: false },
57 el(SelectControl, { label: __('Category', 'blockenberg'), value: a.category, options: CATEGORIES,
58 onChange: function (v) { setAttributes({ category: v }); } }),
59 el(SelectControl, { label: __('Difficulty', 'blockenberg'), value: a.difficulty,
60 options: [{ label: 'Mixed', value: 'mixed' }, { label: 'Easy', value: 'easy' }, { label: 'Medium', value: 'medium' }, { label: 'Hard', value: 'hard' }],
61 onChange: function (v) { setAttributes({ difficulty: v }); } }),
62 el(RangeControl, { label: __('Questions per Round', 'blockenberg'), value: a.questionsPerRound, min: 3, max: 30,
63 onChange: function (v) { setAttributes({ questionsPerRound: v }); } }),
64 el(RangeControl, { label: __('Seconds per Question', 'blockenberg'), value: a.timePerQuestion, min: 5, max: 60,
65 onChange: function (v) { setAttributes({ timePerQuestion: v }); } }),
66 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Timer', 'blockenberg'), checked: a.showTimer, onChange: function (v) { setAttributes({ showTimer: v }); } }),
67 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Progress Bar', 'blockenberg'), checked: a.showProgress, onChange: function (v) { setAttributes({ showProgress: v }); } }),
68 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Answer Explanation', 'blockenberg'), checked: a.showExplanation, onChange: function (v) { setAttributes({ showExplanation: v }); } })
69 ),
70
71 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
72 getTypoControl(props, 'titleTypo', __('Title', 'blockenberg')),
73 getTypoControl(props, 'subtitleTypo', __('Subtitle', 'blockenberg'))
74 ),
75 el(PanelColorSettings, {
76 title: __('Colors', 'blockenberg'), initialOpen: false,
77 colorSettings: [
78 { label: __('Accent', 'blockenberg'), value: a.accentColor, onChange: function (v) { setAttributes({ accentColor: v || '#6366f1' }); } },
79 { label: __('Correct Answer', 'blockenberg'), value: a.correctColor, onChange: function (v) { setAttributes({ correctColor: v || '#22c55e' }); } },
80 { label: __('Wrong Answer', 'blockenberg'), value: a.wrongColor, onChange: function (v) { setAttributes({ wrongColor: v || '#ef4444' }); } },
81 { label: __('Card Background', 'blockenberg'), value: a.cardBg, onChange: function (v) { setAttributes({ cardBg: v || '#ffffff' }); } },
82 { label: __('Section Background', 'blockenberg'), value: a.sectionBg, onChange: function (v) { setAttributes({ sectionBg: v || '#f0f4ff' }); } },
83 { label: __('Title Color', 'blockenberg'), value: a.titleColor, onChange: function (v) { setAttributes({ titleColor: v || '#1e1b4b' }); } }
84 ]
85 })
86 ),
87 el('div', blockProps,
88 el(RichText, { tagName: 'h3', className: 'bkbg-trv-title', value: a.title,
89 onChange: function (v) { setAttributes({ title: v }); },
90 placeholder: 'Trivia Challenge',
91 style: { color: a.titleColor, textAlign: 'center', margin: '0 0 4px' } }),
92 el(RichText, { tagName: 'p', className: 'bkbg-trv-subtitle', value: a.subtitle,
93 onChange: function (v) { setAttributes({ subtitle: v }); },
94 placeholder: 'Test your knowledge!',
95 style: { color: a.titleColor, opacity: 0.65, textAlign: 'center', margin: '0 0 18px' } }),
96
97 // Question card preview
98 el('div', { style: { maxWidth: 640, margin: '0 auto' } },
99 // Progress bar
100 a.showProgress && el('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 } },
101 el('div', { style: { flex: 1, height: 8, background: '#e5e7eb', borderRadius: 99 } },
102 el('div', { style: { width: '30%', height: '100%', background: a.accentColor, borderRadius: 99, transition: 'width 0.4s' } })
103 ),
104 el('span', { style: { fontSize: 13, fontWeight: 600, color: a.titleColor, opacity: 0.6 } }, '3 / ' + a.questionsPerRound)
105 ),
106 // Timer
107 a.showTimer && el('div', { style: { display: 'flex', justifyContent: 'center', marginBottom: 12 } },
108 el('div', { style: { display: 'flex', alignItems: 'center', gap: 6, background: a.accentColor + '18', borderRadius: 99, padding: '4px 14px' } },
109 el('div', { style: { width: 8, height: 8, borderRadius: '50%', background: a.accentColor, animation: 'none' } }),
110 el('span', { style: { fontWeight: 700, fontSize: 15, color: a.accentColor } }, a.timePerQuestion + 's')
111 )
112 ),
113 // Question card
114 el('div', { style: { background: a.cardBg, borderRadius: 14, boxShadow: '0 2px 20px rgba(0,0,0,0.08)', padding: '24px 20px', marginBottom: 14 } },
115 el('div', { style: { fontSize: 13, color: a.accentColor, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 1, marginBottom: 8 } }, 'Science & Nature'),
116 el('div', { style: { fontSize: 19, fontWeight: 700, color: a.titleColor, lineHeight: 1.4, marginBottom: 18 } }, DEMO_Q),
117 el('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 } },
118 DEMO_A.map(function (ans, i) {
119 return el('button', {
120 key: i,
121 style: {
122 border: '2px solid ' + a.accentColor + '44',
123 borderRadius: 10, padding: '12px 14px',
124 background: 'transparent', cursor: 'pointer',
125 fontSize: 15, fontWeight: 600, color: a.titleColor,
126 textAlign: 'left', transition: 'all 0.15s'
127 }
128 }, ans);
129 })
130 )
131 )
132 )
133 )
134 );
135 }
136
137 registerBlockType('blockenberg/trivia-game', {
138 edit: EditorPreview,
139 save: function (props) {
140 var a = props.attributes;
141 var bp = (function () {
142 var tv = Object.assign({}, _tvf(a.titleTypo, '--bktrv-tt-'), _tvf(a.subtitleTypo, '--bktrv-st-'));
143 var parts = []; Object.keys(tv).forEach(function (k) { parts.push(k + ':' + tv[k]); });
144 return useBlockProps.save(parts.length ? { style: parts.join(';') } : {});
145 })();
146 return el('div', bp,
147 el('div', { className: 'bkbg-trv-app', 'data-opts': JSON.stringify(a) },
148 el(RichText.Content, { tagName: 'h3', className: 'bkbg-trv-title', value: a.title }),
149 el(RichText.Content, { tagName: 'p', className: 'bkbg-trv-subtitle', value: a.subtitle })
150 )
151 );
152 }
153 });
154 }() );
155