PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.10
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.10
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 / resource-hub / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.10, at blocks/resource-hub/index.js

152 lines 13.0 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 __ = wp.i18n.__;
4 var registerBlockType = wp.blocks.registerBlockType;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var useBlockProps = wp.blockEditor.useBlockProps;
7 var RichText = wp.blockEditor.RichText;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var PanelBody = wp.components.PanelBody;
10 var ToggleControl = wp.components.ToggleControl;
11 var RangeControl = wp.components.RangeControl;
12 var SelectControl = wp.components.SelectControl;
13 var TextControl = wp.components.TextControl;
14 var TextareaControl = wp.components.TextareaControl;
15 var Button = wp.components.Button;
16
17 var typeIcons = { guide: '📖', video: '🎬', template: '📋', tool: '🛠', podcast: '🎙', other: '📌' };
18
19 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
20 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
21
22 registerBlockType('blockenberg/resource-hub', {
23 edit: function (props) {
24 var attr = props.attributes;
25 var setAttr = props.setAttributes;
26 var TC = getTypoControl();
27
28 function updateResource(idx, key, val) {
29 var resources = (attr.resources || []).map(function (r, i) {
30 return i === idx ? Object.assign({}, r, {[key]: val}) : r;
31 });
32 setAttr({ resources: resources });
33 }
34
35 var inspector = el(InspectorControls, null,
36 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true },
37 el(SelectControl, {
38 __nextHasNoMarginBottom: true,
39 label: __('Layout', 'blockenberg'),
40 value: attr.layout,
41 options: [
42 { label: 'Grid', value: 'grid' },
43 { label: 'List', value: 'list' },
44 { label: 'Featured First (large + grid)', value: 'featured' }
45 ],
46 onChange: function (v) { setAttr({ layout: v }); }
47 }),
48 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Columns', 'blockenberg'), value: attr.columns, min: 2, max: 4, onChange: function (v) { setAttr({ columns: v }); } }),
49 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Category Filter', 'blockenberg'), checked: attr.showFilter, onChange: function (v) { setAttr({ showFilter: v }); } }),
50 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Resource Type Badge', 'blockenberg'), checked: attr.showType, onChange: function (v) { setAttr({ showType: v }); } }),
51 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Card CTA Label', 'blockenberg'), value: attr.ctaLabel, onChange: function (v) { setAttr({ ctaLabel: v }); } }),
52 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Max Width (px)', 'blockenberg'), value: attr.maxWidth, min: 600, max: 1600, onChange: function (v) { setAttr({ maxWidth: v }); } }),
53 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Padding Top (px)', 'blockenberg'), value: attr.paddingTop, min: 0, max: 200, onChange: function (v) { setAttr({ paddingTop: v }); } }),
54 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Padding Bottom (px)', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttr({ paddingBottom: v }); } })
55 ),
56 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
57 TC && el(TC, { label: __('Heading', 'blockenberg'), value: attr.headingTypo || {}, onChange: function(v) { setAttr({ headingTypo: v }); } }),
58 TC && el(TC, { label: __('Subtext', 'blockenberg'), value: attr.subtextTypo || {}, onChange: function(v) { setAttr({ subtextTypo: v }); } })
59 ),
60 el(PanelBody, { title: __('Resources', 'blockenberg'), initialOpen: false },
61 (attr.resources || []).map(function (r, idx) {
62 return el(PanelBody, { key: idx, title: (r.title || 'Resource ' + (idx + 1)), initialOpen: false },
63 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Title', 'blockenberg'), value: r.title, onChange: function (v) { updateResource(idx, 'title', v); } }),
64 el(TextareaControl, { __nextHasNoMarginBottom: true, label: __('Description', 'blockenberg'), value: r.description, onChange: function (v) { updateResource(idx, 'description', v); } }),
65 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Category', 'blockenberg'), value: r.category, onChange: function (v) { updateResource(idx, 'category', v); } }),
66 el(SelectControl, { __nextHasNoMarginBottom: true, label: __('Type', 'blockenberg'), value: r.type, options: [{ label: 'Guide', value: 'guide' }, { label: 'Video', value: 'video' }, { label: 'Template', value: 'template' }, { label: 'Tool', value: 'tool' }, { label: 'Podcast', value: 'podcast' }, { label: 'Other', value: 'other' }], onChange: function (v) { updateResource(idx, 'type', v); } }),
67 el(TextControl, { __nextHasNoMarginBottom: true, label: __('URL', 'blockenberg'), value: r.url, onChange: function (v) { updateResource(idx, 'url', v); } }),
68 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Image URL (optional)', 'blockenberg'), value: r.imageUrl, onChange: function (v) { updateResource(idx, 'imageUrl', v); } }),
69 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Featured (large card)', 'blockenberg'), checked: !!r.featured, onChange: function (v) { updateResource(idx, 'featured', v); } }),
70 el(Button, { isDestructive: true, variant: 'secondary', onClick: function () { setAttr({ resources: (attr.resources || []).filter(function (_, i) { return i !== idx; }) }); } }, __('Remove', 'blockenberg'))
71 );
72 }),
73 el(Button, { isPrimary: true, variant: 'primary', onClick: function () { setAttr({ resources: (attr.resources || []).concat([{ title: 'New Resource', description: 'Description', category: 'Guides', type: 'guide', imageUrl: '', url: '#', featured: false }]) }); } }, __('+ Add Resource', 'blockenberg'))
74 ),
75 el(PanelColorSettings, {
76 title: __('Colors', 'blockenberg'),
77 initialOpen: false,
78 colorSettings: [
79 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#ffffff' }); } },
80 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { setAttr({ headingColor: v || '#111827' }); } },
81 { label: __('Subtext', 'blockenberg'), value: attr.subColor, onChange: function (v) { setAttr({ subColor: v || '#6b7280' }); } },
82 { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowColor, onChange: function (v) { setAttr({ eyebrowColor: v || '#6366f1' }); } },
83 { label: __('Card BG', 'blockenberg'), value: attr.cardBg, onChange: function (v) { setAttr({ cardBg: v || '#f8fafc' }); } },
84 { label: __('Card Border', 'blockenberg'), value: attr.cardBorder, onChange: function (v) { setAttr({ cardBorder: v || '#e2e8f0' }); } },
85 { label: __('Filter Pill BG', 'blockenberg'), value: attr.filterBg, onChange: function (v) { setAttr({ filterBg: v || '#f1f5f9' }); } },
86 { label: __('Filter Active BG', 'blockenberg'), value: attr.filterActiveBg, onChange: function (v) { setAttr({ filterActiveBg: v || '#6366f1' }); } },
87 { label: __('CTA BG', 'blockenberg'), value: attr.ctaBg, onChange: function (v) { setAttr({ ctaBg: v || '#6366f1' }); } },
88 { label: __('CTA Text', 'blockenberg'), value: attr.ctaColor, onChange: function (v) { setAttr({ ctaColor: v || '#ffffff' }); } }
89 ]
90 })
91 );
92
93 var blockProps = useBlockProps((function () {
94 var _tvFn = getTypoCssVars();
95 var s = {};
96 if (_tvFn) {
97 Object.assign(s, _tvFn(attr.headingTypo || {}, '--bkrh-ht-'));
98 Object.assign(s, _tvFn(attr.subtextTypo || {}, '--bkrh-st-'));
99 }
100 return { className: 'bkbg-rhb-editor', style: s };
101 })());
102
103 /* Unique categories for filter preview */
104 var cats = ['All'].concat((attr.resources || []).reduce(function (acc, r) {
105 if (r.category && acc.indexOf(r.category) === -1) acc.push(r.category);
106 return acc;
107 }, []));
108
109 return el('div', blockProps,
110 inspector,
111 el('div', { style: { background: attr.bgColor, padding: '40px', borderRadius: '8px', fontFamily: 'sans-serif' } },
112 el('div', { style: { textAlign: 'center', marginBottom: '40px' } },
113 el(RichText, { tagName: 'p', value: attr.eyebrow, onChange: function (v) { setAttr({ eyebrow: v }); }, placeholder: __('Eyebrow…', 'blockenberg'), style: { color: attr.eyebrowColor, fontWeight: 600, fontSize: '13px', letterSpacing: '0.1em', textTransform: 'uppercase', margin: '0 0 8px' } }),
114 el(RichText, { tagName: 'h2', value: attr.heading, onChange: function (v) { setAttr({ heading: v }); }, placeholder: __('Heading…', 'blockenberg'), className: 'bkbg-rhb-heading', style: { color: attr.headingColor, margin: '0 0 12px' } }),
115 el(RichText, { tagName: 'p', value: attr.subtext, onChange: function (v) { setAttr({ subtext: v }); }, placeholder: __('Subtext…', 'blockenberg'), className: 'bkbg-rhb-sub', style: { color: attr.subColor, maxWidth: '600px', margin: '0 auto' } })
116 ),
117 /* Filter pills */
118 attr.showFilter && el('div', { style: { display: 'flex', gap: '8px', flexWrap: 'wrap', justifyContent: 'center', marginBottom: '32px' } },
119 cats.map(function (cat, i) {
120 var isAll = cat === 'All';
121 return el('span', { key: i, style: { background: isAll ? attr.filterActiveBg : attr.filterBg, color: isAll ? attr.filterActiveColor : attr.filterColor, borderRadius: '20px', padding: '6px 16px', fontSize: '13px', fontWeight: 600, cursor: 'pointer' } }, cat);
122 })
123 ),
124 /* Resource cards */
125 el('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(' + attr.columns + ',1fr)', gap: '20px' } },
126 (attr.resources || []).map(function (r, i) {
127 return el('div', { key: i, style: { background: attr.cardBg, border: '1px solid ' + attr.cardBorder, borderRadius: '12px', overflow: 'hidden' } },
128 r.imageUrl && el('img', { src: r.imageUrl, style: { width: '100%', height: '140px', objectFit: 'cover', display: 'block' }, alt: '' }),
129 !r.imageUrl && el('div', { style: { height: '100px', background: 'linear-gradient(135deg,' + attr.accentColor + '22,' + attr.accentColor + '44)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '40px' } }, typeIcons[r.type] || '📌'),
130 el('div', { style: { padding: '16px' } },
131 attr.showType && el('span', { style: { fontSize: '11px', fontWeight: 700, textTransform: 'uppercase', color: attr.accentColor, letterSpacing: '0.08em' } }, (typeIcons[r.type] || '') + ' ' + (r.type || 'resource')),
132 el('div', { style: { color: attr.titleColor, fontWeight: 700, fontSize: '15px', margin: '6px 0 4px' } }, r.title),
133 el('div', { style: { color: attr.descColor, fontSize: '13px', lineHeight: 1.5, marginBottom: '12px' } }, r.description),
134 el('a', { href: r.url, style: { display: 'inline-block', background: attr.ctaBg, color: attr.ctaColor, borderRadius: '6px', padding: '7px 14px', fontSize: '13px', fontWeight: 600, textDecoration: 'none' } }, attr.ctaLabel)
135 )
136 );
137 })
138 )
139 )
140 );
141 },
142
143 save: function (props) {
144 var attr = props.attributes;
145 var useBlockProps = wp.blockEditor.useBlockProps;
146 return el('div', useBlockProps.save(),
147 el('div', { className: 'bkbg-rhb-app', 'data-opts': JSON.stringify(attr) })
148 );
149 }
150 });
151 }() );
152