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 / project-brief / index.js

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

303 lines 21.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 Fragment = wp.element.Fragment;
4 var registerBlockType = wp.blocks.registerBlockType;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var useBlockProps = wp.blockEditor.useBlockProps;
7 var PanelBody = wp.components.PanelBody;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var ToggleControl = wp.components.ToggleControl;
10 var RangeControl = wp.components.RangeControl;
11 var SelectControl = wp.components.SelectControl;
12 var TextControl = wp.components.TextControl;
13 var TextareaControl = wp.components.TextareaControl;
14 var Button = wp.components.Button;
15
16 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
17 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
18
19 var statusOptions = [
20 { label: '📋 Planning', value: 'planning' },
21 { label: '🚀 Active', value: 'active' },
22 { label: '🔍 In Review', value: 'review' },
23 { label: '�
24 Complete', value: 'complete' },
25 { label: '⏸ On Hold', value: 'on-hold' }
26 ];
27 var levelOptions = [
28 { label: 'Low', value: 'low' },
29 { label: 'Medium', value: 'medium' },
30 { label: 'High', value: 'high' }
31 ];
32
33 function statusInfo(s) {
34 var map = {
35 'planning': { label: '📋 Planning', bg: '#dbeafe', color: '#1e3a8a' },
36 'active': { label: '🚀 Active', bg: '#dcfce7', color: '#14532d' },
37 'review': { label: '🔍 In Review', bg: '#fef9c3', color: '#713f12' },
38 'complete': { label: '�
39 Complete', bg: '#e0e7ff', color: '#3730a3' },
40 'on-hold': { label: '⏸ On Hold', bg: '#fee2e2', color: '#991b1b' }
41 };
42 return map[s] || map['planning'];
43 }
44
45 function riskColor(level) {
46 if (level === 'high') return { bg: '#fef2f2', color: '#991b1b', dot: '#ef4444' };
47 if (level === 'medium') return { bg: '#fffbeb', color: '#92400e', dot: '#f59e0b' };
48 return { bg: '#f0fdf4', color: '#14532d', dot: '#22c55e' };
49 }
50
51 function upd(arr, idx, field, val) {
52 return arr.map(function (e, i) {
53 if (i !== idx) return e;
54 var u = {}; u[field] = val;
55 return Object.assign({}, e, u);
56 });
57 }
58
59 function sectionHead(label, a) {
60 return el('div', { style: { fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.09em', color: a.accentColor, borderBottom: '2px solid ' + a.accentColor, paddingBottom: 6, marginBottom: 12 } }, label);
61 }
62
63 registerBlockType('blockenberg/project-brief', {
64 edit: function (props) {
65 var a = props.attributes;
66 var set = props.setAttributes;
67 var TC = getTypoControl();
68 var blockProps = useBlockProps((function () {
69 var _tv = getTypoCssVars();
70 var s = {};
71 if (_tv) {
72 Object.assign(s, _tv(a.titleTypo || {}, '--bkbg-pjb-tt-'));
73 Object.assign(s, _tv(a.bodyTypo || {}, '--bkbg-pjb-bd-'));
74 }
75 return { className: 'bkbg-pb-editor-wrap', style: s };
76 })());
77 var si = statusInfo(a.status);
78
79 var preview = el('div', { className: 'bkbg-pb-wrap', style: { border: '1px solid ' + a.borderColor, borderRadius: a.borderRadius + 'px', overflow: 'hidden', background: a.bgColor } },
80 // Header
81 el('div', { style: { background: a.headerBg, padding: '20px 24px' } },
82 el('div', { style: { display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' } },
83 el('div', null,
84 el('h2', { className: 'bkbg-pb-title', style: { margin: '0 0 4px', color: a.headerColor } }, a.projectName),
85 el('div', { style: { fontSize: 12, color: a.metaColor } }, a.projectType)
86 ),
87 el('span', { style: { background: si.bg, color: si.color, padding: '4px 12px', borderRadius: 100, fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap' } }, si.label)
88 ),
89 el('div', { style: { marginTop: 12, display: 'flex', gap: 20, flexWrap: 'wrap' } },
90 el('span', { style: { fontSize: 12, color: a.metaColor } }, '👤 Owner: ' + a.owner),
91 el('span', { style: { fontSize: 12, color: a.metaColor } }, '🏢 Client: ' + a.client),
92 a.showDates && el('span', { style: { fontSize: 12, color: a.metaColor } }, '�
93 ' + a.startDate + '' + a.endDate),
94 a.showBudget && a.budget && el('span', { style: { fontSize: 12, color: a.metaColor } }, '💰 ' + a.budget)
95 )
96 ),
97 // Body
98 el('div', { style: { padding: '20px 24px', display: 'grid', gap: 20 } },
99 // Overview
100 el('div', null,
101 sectionHead('Project Overview', a),
102 el('p', { style: { margin: 0, color: a.bodyTextColor } }, a.overview)
103 ),
104 // Goals + Deliverables side by side
105 el('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 } },
106 el('div', { style: { background: a.sectionBg, padding: 16, borderRadius: 8 } },
107 sectionHead('Goals', a),
108 el('ul', { style: { margin: 0, padding: 0, listStyle: 'none' } },
109 a.goals.map(function (g, i) {
110 return el('li', { key: i, style: { display: 'flex', gap: 8, marginBottom: 6, alignItems: 'flex-start' } },
111 el('span', { style: { color: a.goalDotColor, fontWeight: 800, marginTop: 1, flexShrink: 0 } }, ''),
112 el('span', { style: { color: a.bodyTextColor } }, g)
113 );
114 })
115 )
116 ),
117 el('div', { style: { background: a.sectionBg, padding: 16, borderRadius: 8 } },
118 sectionHead('Deliverables', a),
119 el('ul', { style: { margin: 0, padding: 0, listStyle: 'none' } },
120 a.deliverables.map(function (d, i) {
121 return el('li', { key: i, style: { display: 'flex', gap: 8, marginBottom: 6, alignItems: 'flex-start' } },
122 el('span', { style: { color: a.delivDotColor, fontWeight: 800, marginTop: 1, flexShrink: 0 } }, ''),
123 el('span', { style: { color: a.bodyTextColor } }, d)
124 );
125 })
126 )
127 )
128 ),
129 // Stakeholders
130 el('div', null,
131 sectionHead('Stakeholders', a),
132 el('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 8 } },
133 a.stakeholders.map(function (s, i) {
134 return el('div', { key: i, style: { background: a.sectionBg, padding: '10px 14px', borderRadius: 8, borderLeft: '3px solid ' + a.accentColor } },
135 el('div', { style: { fontWeight: 700, color: a.sectionTitleColor } }, s.name),
136 el('div', { style: { color: a.bodyTextColor, opacity: .75 } }, s.role)
137 );
138 })
139 )
140 ),
141 // Risks
142 a.risks.length > 0 && el('div', null,
143 sectionHead('Risks', a),
144 el('div', { style: { display: 'grid', gap: 6 } },
145 a.risks.map(function (r, i) {
146 var lc = riskColor(r.likelihood);
147 var ic = riskColor(r.impact);
148 return el('div', { key: i, style: { display: 'grid', gridTemplateColumns: '1fr 100px 100px', gap: 8, padding: '8px 14px', background: a.sectionBg, borderRadius: 8, alignItems: 'center', borderLeft: '3px solid ' + lc.dot } },
149 el('span', { style: { color: a.bodyTextColor } }, r.risk),
150 el('span', { style: { background: lc.bg, color: lc.color, padding: '2px 8px', borderRadius: 100, fontSize: 11, fontWeight: 700, textAlign: 'center' } }, 'L: ' + r.likelihood),
151 el('span', { style: { background: ic.bg, color: ic.color, padding: '2px 8px', borderRadius: 100, fontSize: 11, fontWeight: 700, textAlign: 'center' } }, 'I: ' + r.impact)
152 );
153 })
154 )
155 ),
156 // Notes
157 a.showNotes && a.notes && el('div', null,
158 sectionHead('Additional Notes', a),
159 el('p', { style: { margin: 0, color: a.bodyTextColor, fontStyle: 'italic' } }, a.notes)
160 )
161 )
162 );
163
164 return el(Fragment, null,
165 el('div', blockProps, preview),
166 el(InspectorControls, null,
167 // Project Info
168 el(PanelBody, { title: 'Project Info', initialOpen: true },
169 el(TextControl, { label: 'Project Name', value: a.projectName, __nextHasNoMarginBottom: true, onChange: function (v) { set({ projectName: v }); } }),
170 el('div', { style: { marginTop: 8 } },
171 el(TextControl, { label: 'Project Type', value: a.projectType, __nextHasNoMarginBottom: true, onChange: function (v) { set({ projectType: v }); } })
172 ),
173 el('div', { style: { marginTop: 8 } },
174 el(SelectControl, { label: 'Status', value: a.status, options: statusOptions, __nextHasNoMarginBottom: true, onChange: function (v) { set({ status: v }); } })
175 ),
176 el('div', { style: { marginTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 } },
177 el(TextControl, { label: 'Client', value: a.client, __nextHasNoMarginBottom: true, onChange: function (v) { set({ client: v }); } }),
178 el(TextControl, { label: 'Owner', value: a.owner, __nextHasNoMarginBottom: true, onChange: function (v) { set({ owner: v }); } })
179 ),
180 el('div', { style: { marginTop: 8 } },
181 el(ToggleControl, { label: 'Show Dates', checked: a.showDates, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showDates: v }); } })
182 ),
183 a.showDates && el('div', { style: { marginTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 } },
184 el(TextControl, { label: 'Start Date', value: a.startDate, __nextHasNoMarginBottom: true, onChange: function (v) { set({ startDate: v }); } }),
185 el(TextControl, { label: 'End Date', value: a.endDate, __nextHasNoMarginBottom: true, onChange: function (v) { set({ endDate: v }); } })
186 ),
187 el('div', { style: { marginTop: 8 } },
188 el(ToggleControl, { label: 'Show Budget', checked: a.showBudget, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showBudget: v }); } })
189 ),
190 a.showBudget && el('div', { style: { marginTop: 8 } },
191 el(TextControl, { label: 'Budget', value: a.budget, __nextHasNoMarginBottom: true, onChange: function (v) { set({ budget: v }); } })
192 )
193 ),
194 // Overview
195 el(PanelBody, { title: 'Overview', initialOpen: false },
196 el(TextareaControl, { label: 'Project Overview', value: a.overview, rows: 5, __nextHasNoMarginBottom: true, onChange: function (v) { set({ overview: v }); } })
197 ),
198 // Goals
199 el(PanelBody, { title: 'Goals', initialOpen: false },
200 a.goals.map(function (g, i) {
201 return el('div', { key: i, style: { display: 'flex', gap: 6, marginBottom: 6, alignItems: 'center' } },
202 el(TextControl, { label: '', value: g, __nextHasNoMarginBottom: true, onChange: function (v) { set({ goals: a.goals.map(function (x, j) { return j === i ? v : x; }) }); } }),
203 el(Button, { isDestructive: true, variant: 'link', onClick: function () { set({ goals: a.goals.filter(function (_, j) { return j !== i; }) }); } }, '')
204 );
205 }),
206 el(Button, { variant: 'primary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ goals: a.goals.concat(['New goal']) }); } }, '+ Add Goal')
207 ),
208 // Deliverables
209 el(PanelBody, { title: 'Deliverables', initialOpen: false },
210 a.deliverables.map(function (d, i) {
211 return el('div', { key: i, style: { display: 'flex', gap: 6, marginBottom: 6, alignItems: 'center' } },
212 el(TextControl, { label: '', value: d, __nextHasNoMarginBottom: true, onChange: function (v) { set({ deliverables: a.deliverables.map(function (x, j) { return j === i ? v : x; }) }); } }),
213 el(Button, { isDestructive: true, variant: 'link', onClick: function () { set({ deliverables: a.deliverables.filter(function (_, j) { return j !== i; }) }); } }, '')
214 );
215 }),
216 el(Button, { variant: 'primary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ deliverables: a.deliverables.concat(['New deliverable']) }); } }, '+ Add Deliverable')
217 ),
218 // Stakeholders
219 el(PanelBody, { title: 'Stakeholders', initialOpen: false },
220 a.stakeholders.map(function (s, i) {
221 return el('div', { key: i, style: { padding: '8px 10px', border: '1px solid #e5e7eb', borderRadius: 8, background: '#f8fafc', marginBottom: 8 } },
222 el('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: 4 } },
223 el(Button, { isDestructive: true, variant: 'link', style: { fontSize: 11 }, onClick: function () { set({ stakeholders: a.stakeholders.filter(function (_, j) { return j !== i; }) }); } }, '')
224 ),
225 el(TextControl, { label: 'Name', value: s.name, __nextHasNoMarginBottom: true, onChange: function (v) { set({ stakeholders: upd(a.stakeholders, i, 'name', v) }); } }),
226 el('div', { style: { marginTop: 8 } },
227 el(TextControl, { label: 'Role', value: s.role, __nextHasNoMarginBottom: true, onChange: function (v) { set({ stakeholders: upd(a.stakeholders, i, 'role', v) }); } })
228 )
229 );
230 }),
231 el(Button, { variant: 'primary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ stakeholders: a.stakeholders.concat([{ name: 'Name', role: 'Role' }]) }); } }, '+ Add Stakeholder')
232 ),
233 // Risks
234 el(PanelBody, { title: 'Risks', initialOpen: false },
235 a.risks.map(function (r, i) {
236 return el('div', { key: i, style: { padding: '8px 10px', border: '1px solid #e5e7eb', borderRadius: 8, background: '#f8fafc', marginBottom: 8 } },
237 el('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: 4 } },
238 el(Button, { isDestructive: true, variant: 'link', style: { fontSize: 11 }, onClick: function () { set({ risks: a.risks.filter(function (_, j) { return j !== i; }) }); } }, '')
239 ),
240 el(TextareaControl, { label: 'Risk', value: r.risk, rows: 2, __nextHasNoMarginBottom: true, onChange: function (v) { set({ risks: upd(a.risks, i, 'risk', v) }); } }),
241 el('div', { style: { marginTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 } },
242 el(SelectControl, { label: 'Likelihood', value: r.likelihood, options: levelOptions, __nextHasNoMarginBottom: true, onChange: function (v) { set({ risks: upd(a.risks, i, 'likelihood', v) }); } }),
243 el(SelectControl, { label: 'Impact', value: r.impact, options: levelOptions, __nextHasNoMarginBottom: true, onChange: function (v) { set({ risks: upd(a.risks, i, 'impact', v) }); } })
244 )
245 );
246 }),
247 el(Button, { variant: 'primary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ risks: a.risks.concat([{ risk: 'New risk', likelihood: 'low', impact: 'medium' }]) }); } }, '+ Add Risk')
248 ),
249 // Notes
250 el(PanelBody, { title: 'Additional Notes', initialOpen: false },
251 el(ToggleControl, { label: 'Show Notes', checked: a.showNotes, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showNotes: v }); } }),
252 el('div', { style: { marginTop: 8 } },
253 el(TextareaControl, { label: 'Notes', value: a.notes, rows: 4, __nextHasNoMarginBottom: true, onChange: function (v) { set({ notes: v }); } })
254 )
255 ),
256 // Typography
257 el(PanelBody, { title: 'Typography', initialOpen: false },
258 TC && el(TC, { label: 'Title', value: a.titleTypo || {}, onChange: function (v) { set({ titleTypo: v }); } }),
259 TC && el(TC, { label: 'Body Text', value: a.bodyTypo || {}, onChange: function (v) { set({ bodyTypo: v }); } })
260 ),
261 el(PanelBody, { title: 'Spacing', initialOpen: false },
262 el(RangeControl, { label: 'Border Radius (px)', value: a.borderRadius, min: 0, max: 24, __nextHasNoMarginBottom: true, onChange: function (v) { set({ borderRadius: v }); } })
263 ),
264 // Colors
265 el(PanelColorSettings, {
266 title: 'Header Colors',
267 initialOpen: false,
268 colorSettings: [
269 { label: 'Header BG', value: a.headerBg, onChange: function (v) { set({ headerBg: v || '#0f172a' }); } },
270 { label: 'Header Text', value: a.headerColor, onChange: function (v) { set({ headerColor: v || '#ffffff' }); } },
271 { label: 'Meta Text', value: a.metaColor, onChange: function (v) { set({ metaColor: v || '#94a3b8' }); } }
272 ]
273 }),
274 el(PanelColorSettings, {
275 title: 'Body Colors',
276 initialOpen: false,
277 colorSettings: [
278 { label: 'Block BG', value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#ffffff' }); } },
279 { label: 'Border', value: a.borderColor, onChange: function (v) { set({ borderColor: v || '#e5e7eb' }); } },
280 { label: 'Section BG', value: a.sectionBg, onChange: function (v) { set({ sectionBg: v || '#f8fafc' }); } },
281 { label: 'Section Heading', value: a.sectionTitleColor,onChange: function (v) { set({ sectionTitleColor: v || '#111827' }); } },
282 { label: 'Body Text', value: a.bodyTextColor, onChange: function (v) { set({ bodyTextColor: v || '#374151' }); } },
283 { label: 'Accent', value: a.accentColor, onChange: function (v) { set({ accentColor: v || '#3b82f6' }); } },
284 { label: 'Goal Check', value: a.goalDotColor, onChange: function (v) { set({ goalDotColor: v || '#3b82f6' }); } },
285 { label: 'Deliverable →', value: a.delivDotColor, onChange: function (v) { set({ delivDotColor: v || '#10b981' }); } }
286 ]
287 })
288 )
289 );
290 },
291
292 save: function (props) {
293 var useBlockProps = wp.blockEditor.useBlockProps;
294 return wp.element.createElement('div', useBlockProps.save(),
295 wp.element.createElement('div', {
296 className: 'bkbg-project-brief-app',
297 'data-opts': JSON.stringify(props.attributes)
298 })
299 );
300 }
301 });
302 }() );
303