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 / job-openings / index.js

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

165 lines 14.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 __ = wp.i18n.__;
4 var useState = wp.element.useState;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var useBlockProps = wp.blockEditor.useBlockProps;
8 var RichText = wp.blockEditor.RichText;
9 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
10 var PanelBody = wp.components.PanelBody;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14 var TextControl = wp.components.TextControl;
15 var Button = wp.components.Button;
16
17 var _TypographyControl, _typoCssVars;
18 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
19 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
20
21 var JOB_TYPES = ['Full-time', 'Part-time', 'Remote', 'Contract', 'Internship'];
22
23 registerBlockType('blockenberg/job-openings', {
24 edit: function (props) {
25 var attributes = props.attributes;
26 var setAttributes = props.setAttributes;
27 var a = attributes;
28
29 var blockProps = useBlockProps((function () {
30 var _tv = getTypoCssVars();
31 var s = { backgroundColor: a.bgColor, paddingTop: a.paddingTop + 'px', paddingBottom: a.paddingBottom + 'px' };
32 Object.assign(s, _tv(a.headingTypo, '--bkbg-jo-h-'));
33 Object.assign(s, _tv(a.eyebrowTypo, '--bkbg-jo-ew-'));
34 Object.assign(s, _tv(a.subtextTypo, '--bkbg-jo-st-'));
35 Object.assign(s, _tv(a.jobTitleTypo, '--bkbg-jo-jt-'));
36 Object.assign(s, _tv(a.jobDescTypo, '--bkbg-jo-jd-'));
37 return { className: 'bkbg-job-wrap', style: s };
38 })());
39
40 function updateJob(idx, key, val) {
41 setAttributes({ jobs: a.jobs.map(function (j, i) { return i === idx ? Object.assign({}, j, { [key]: val }) : j; }) });
42 }
43 function addJob() {
44 setAttributes({ jobs: a.jobs.concat([{ title: 'New Position', department: 'Department', location: 'Remote', type: 'Full-time', url: '#', description: '' }]) });
45 }
46 function removeJob(idx) {
47 setAttributes({ jobs: a.jobs.filter(function (_, i) { return i !== idx; }) });
48 }
49
50 var innerStyle = { maxWidth: a.maxWidth + 'px', margin: '0 auto', padding: '0 24px' };
51
52 function jobCard(j, idx) {
53 return el('div', { key: idx, className: 'bkbg-job-card', style: { background: a.jobCardBg, border: '1px solid ' + a.jobCardBorder, borderRadius: 12, padding: '24px 28px', position: 'relative', marginBottom: a.layout === 'list' ? 16 : 0 } },
54 el(Button, { isDestructive: true, size: 'small', onClick: function () { removeJob(idx); }, style: { position: 'absolute', top: 12, right: 12, fontSize: 10 } }, ''),
55 // Tags row
56 el('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 12, alignItems: 'center' } },
57 el('span', { style: { background: a.deptBg, color: a.deptColor, fontSize: 12, fontWeight: 700, padding: '3px 10px', borderRadius: 999 } }, j.department),
58 el('span', { style: { background: a.typeBg, color: a.typeColor, fontSize: 12, fontWeight: 700, padding: '3px 10px', borderRadius: 999 } }, j.type),
59 el('span', { style: { color: a.locationColor, fontSize: 13 } }, '📍 ', j.location)
60 ),
61 el(RichText, { tagName: 'h3', className: 'bkbg-job-title', value: j.title, onChange: function (v) { updateJob(idx, 'title', v); }, placeholder: __('Job Title…', 'blockenberg'), style: { color: a.jobTitleColor, margin: '0 0 8px' } }),
62 a.showDescription && el(RichText, { tagName: 'p', className: 'bkbg-job-desc', value: j.description, onChange: function (v) { updateJob(idx, 'description', v); }, placeholder: __('Job description…', 'blockenberg'), style: { color: a.jobDescColor, margin: '0 0 16px' } }),
63 // Inline edit fields
64 el('div', { style: { display: 'flex', gap: 10, flexWrap: 'wrap', marginTop: 12 } },
65 el(TextControl, { label: __('Dept', 'blockenberg'), value: j.department, onChange: function (v) { updateJob(idx, 'department', v); }, style: { flex: 1 }, __nextHasNoMarginBottom: true }),
66 el(TextControl, { label: __('Location', 'blockenberg'), value: j.location, onChange: function (v) { updateJob(idx, 'location', v); }, style: { flex: 1 }, __nextHasNoMarginBottom: true }),
67 el(SelectControl, { label: __('Type', 'blockenberg'), value: j.type, options: JOB_TYPES.map(function (t) { return { label: t, value: t }; }), onChange: function (v) { updateJob(idx, 'type', v); }, __nextHasNoMarginBottom: true }),
68 el(TextControl, { label: __('Apply URL', 'blockenberg'), value: j.url, onChange: function (v) { updateJob(idx, 'url', v); }, style: { flex: 2 }, __nextHasNoMarginBottom: true })
69 ),
70 el('a', { href: '#', style: { display: 'inline-block', marginTop: 12, background: a.applyBg, color: a.applyColor, fontWeight: 700, fontSize: 14, padding: '10px 22px', borderRadius: 6, textDecoration: 'none' } }, a.applyLabel)
71 );
72 }
73
74 return el('div', blockProps,
75 el(InspectorControls, null,
76 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
77 el(ToggleControl, { label: __('Show Eyebrow', 'blockenberg'), checked: a.showEyebrow, onChange: function (v) { setAttributes({ showEyebrow: v }); }, __nextHasNoMarginBottom: true }),
78 a.showEyebrow && el(TextControl, { label: __('Eyebrow', 'blockenberg'), value: a.eyebrow, onChange: function (v) { setAttributes({ eyebrow: v }); }, __nextHasNoMarginBottom: true }),
79 el(ToggleControl, { label: __('Show Subtext', 'blockenberg'), checked: a.showSubtext, onChange: function (v) { setAttributes({ showSubtext: v }); }, __nextHasNoMarginBottom: true }),
80 el(ToggleControl, { label: __('Show Description', 'blockenberg'), checked: a.showDescription, onChange: function (v) { setAttributes({ showDescription: v }); }, __nextHasNoMarginBottom: true }),
81 el(ToggleControl, { label: __('Show Filter Tabs', 'blockenberg'), checked: a.showFilter, onChange: function (v) { setAttributes({ showFilter: v }); }, __nextHasNoMarginBottom: true }),
82 a.showFilter && el(SelectControl, { label: __('Filter By', 'blockenberg'), value: a.filterBy, options: [{ label: 'Department', value: 'department' }, { label: 'Job Type', value: 'type' }, { label: 'Location', value: 'location' }], onChange: function (v) { setAttributes({ filterBy: v }); }, __nextHasNoMarginBottom: true }),
83 el(TextControl, { label: __('Apply Button Label', 'blockenberg'), value: a.applyLabel, onChange: function (v) { setAttributes({ applyLabel: v }); }, __nextHasNoMarginBottom: true }),
84 el(ToggleControl, { label: __('Open in New Tab', 'blockenberg'), checked: a.openInNewTab, onChange: function (v) { setAttributes({ openInNewTab: v }); }, __nextHasNoMarginBottom: true })
85 ),
86 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
87 el(SelectControl, { label: __('Layout', 'blockenberg'), value: a.layout, options: [{ label: 'List', value: 'list' }, { label: 'Grid (2 col)', value: 'grid' }], onChange: function (v) { setAttributes({ layout: v }); }, __nextHasNoMarginBottom: true }),
88 el(RangeControl, { label: __('Max Width (px)', 'blockenberg'), value: a.maxWidth, min: 600, max: 1400, onChange: function (v) { setAttributes({ maxWidth: v }); }, __nextHasNoMarginBottom: true }),
89 el(RangeControl, { label: __('Padding Top (px)', 'blockenberg'), value: a.paddingTop, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingTop: v }); }, __nextHasNoMarginBottom: true }),
90 el(RangeControl, { label: __('Padding Bottom (px)', 'blockenberg'), value: a.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingBottom: v }); }, __nextHasNoMarginBottom: true })
91 ),
92
93 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
94 el(getTypographyControl(), { label: __('Heading', 'blockenberg'), value: a.headingTypo, onChange: function (v) { setAttributes({ headingTypo: v }); } }),
95 el(getTypographyControl(), { label: __('Eyebrow', 'blockenberg'), value: a.eyebrowTypo, onChange: function (v) { setAttributes({ eyebrowTypo: v }); } }),
96 el(getTypographyControl(), { label: __('Subtext', 'blockenberg'), value: a.subtextTypo, onChange: function (v) { setAttributes({ subtextTypo: v }); } }),
97 el(getTypographyControl(), { label: __('Job Title', 'blockenberg'), value: a.jobTitleTypo, onChange: function (v) { setAttributes({ jobTitleTypo: v }); } }),
98 el(getTypographyControl(), { label: __('Job Description', 'blockenberg'), value: a.jobDescTypo, onChange: function (v) { setAttributes({ jobDescTypo: v }); } })
99 ),
100 el(PanelColorSettings, {
101 title: __('Colors', 'blockenberg'),
102 initialOpen: false,
103 colorSettings: [
104 { label: __('Background', 'blockenberg'), value: a.bgColor, onChange: function (v) { setAttributes({ bgColor: v || '#ffffff' }); } },
105 { label: __('Eyebrow Color', 'blockenberg'), value: a.eyebrowColor, onChange: function (v) { setAttributes({ eyebrowColor: v || '#7c3aed' }); } },
106 { label: __('Heading Color', 'blockenberg'), value: a.headingColor, onChange: function (v) { setAttributes({ headingColor: v || '#111827' }); } },
107 { label: __('Card BG', 'blockenberg'), value: a.jobCardBg, onChange: function (v) { setAttributes({ jobCardBg: v || '#f9fafb' }); } },
108 { label: __('Dept Tag Color', 'blockenberg'), value: a.deptColor, onChange: function (v) { setAttributes({ deptColor: v || '#7c3aed' }); } },
109 { label: __('Type Tag Color', 'blockenberg'), value: a.typeColor, onChange: function (v) { setAttributes({ typeColor: v || '#15803d' }); } },
110 { label: __('Filter Active BG', 'blockenberg'), value: a.filterActiveBg, onChange: function (v) { setAttributes({ filterActiveBg: v || '#7c3aed' }); } },
111 { label: __('Apply Button BG', 'blockenberg'), value: a.applyBg, onChange: function (v) { setAttributes({ applyBg: v || '#7c3aed' }); } }
112 ]
113 })
114 ),
115
116 el('div', { style: innerStyle },
117 // Header
118 el('div', { style: { textAlign: 'center', marginBottom: 48 } },
119 a.showEyebrow && el('span', { className: 'bkbg-job-eyebrow', style: { display: 'inline-block', background: a.eyebrowBg, color: a.eyebrowColor, padding: '5px 14px', borderRadius: 999, marginBottom: 16 } }, a.eyebrow),
120 el(RichText, { tagName: 'h2', className: 'bkbg-job-heading', value: a.heading, onChange: function (v) { setAttributes({ heading: v }); }, placeholder: __('Heading…', 'blockenberg'), style: { color: a.headingColor, margin: '0 0 16px' } }),
121 a.showSubtext && el(RichText, { tagName: 'p', className: 'bkbg-job-subtext', value: a.subtext, onChange: function (v) { setAttributes({ subtext: v }); }, placeholder: __('Subtext…', 'blockenberg'), style: { color: a.subtextColor, margin: '0 auto', maxWidth: 600 } })
122 ),
123
124 // Filter tabs preview
125 a.showFilter && el('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 32, justifyContent: 'center' } },
126 el('button', { style: { background: a.filterActiveBg, color: a.filterActiveColor, border: 'none', padding: '8px 18px', borderRadius: 999, fontWeight: 700, fontSize: 13, cursor: 'default' } }, 'All'),
127 Array.from(new Set(a.jobs.map(function (j) { return j[a.filterBy]; }))).map(function (val, idx) {
128 return el('button', { key: idx, style: { background: a.filterBg, color: a.filterColor, border: 'none', padding: '8px 18px', borderRadius: 999, fontWeight: 600, fontSize: 13, cursor: 'default' } }, val);
129 })
130 ),
131
132 // Job listings
133 el('div', {
134 style: a.layout === 'grid'
135 ? { display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 20 }
136 : { display: 'flex', flexDirection: 'column', gap: 0 }
137 },
138 a.jobs.map(function (j, idx) { return jobCard(j, idx); }),
139 el('div', {
140 onClick: addJob,
141 style: { border: '2px dashed #d1d5db', borderRadius: 12, padding: 24, textAlign: 'center', cursor: 'pointer', marginTop: a.layout === 'list' ? 16 : 0 }
142 },
143 el('span', { style: { fontSize: 13, color: '#9ca3af' } }, '+ Add Job Posting')
144 )
145 )
146 )
147 );
148 },
149 save: function (props) {
150 var useBlockProps = wp.blockEditor.useBlockProps;
151 var a = props.attributes;
152 var _tv = getTypoCssVars();
153 var s = {};
154 Object.assign(s, _tv(a.headingTypo, '--bkbg-jo-h-'));
155 Object.assign(s, _tv(a.eyebrowTypo, '--bkbg-jo-ew-'));
156 Object.assign(s, _tv(a.subtextTypo, '--bkbg-jo-st-'));
157 Object.assign(s, _tv(a.jobTitleTypo, '--bkbg-jo-jt-'));
158 Object.assign(s, _tv(a.jobDescTypo, '--bkbg-jo-jd-'));
159 return el('div', useBlockProps.save({ style: s }),
160 el('div', { className: 'bkbg-job-app', 'data-opts': JSON.stringify(props.attributes) })
161 );
162 }
163 });
164 }() );
165