PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / feature-request / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/feature-request/frontend.js

136 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 function typoCssVarsForEl(typo, prefix, el) {
5 if (!typo || typeof typo !== 'object') return;
6 var m = {
7 family: 'font-family', weight: 'font-weight',
8 transform: 'text-transform', style: 'font-style', decoration: 'text-decoration'
9 };
10 Object.keys(m).forEach(function (k) {
11 if (typo[k]) el.style.setProperty(prefix + m[k], typo[k]);
12 });
13 var r = {
14 size: 'font-size', lineHeight: 'line-height',
15 letterSpacing: 'letter-spacing', wordSpacing: 'word-spacing'
16 };
17 Object.keys(r).forEach(function (k) {
18 ['Desktop', 'Tablet', 'Mobile'].forEach(function (d, i) {
19 var v = typo[k + d];
20 if (v === undefined || v === '') return;
21 var suffix = ['-d', '-t', '-m'][i];
22 var unit = typo[k + 'Unit'] || ('size' === k ? 'px' : (k === 'lineHeight' ? '' : 'px'));
23 el.style.setProperty(prefix + r[k] + suffix, v + unit);
24 });
25 });
26 }
27
28 function mk(tag, cls, styles) { var d = document.createElement(tag); if (cls) d.className = cls; if (styles) Object.keys(styles).forEach(function (k) { d.style[k] = styles[k]; }); return d; }
29 function tx(tag, cls, text, styles) { var d = mk(tag, cls, styles); d.textContent = text; return d; }
30 function ap(p) { Array.prototype.slice.call(arguments, 1).forEach(function (c) { if (c) p.appendChild(c); }); return p; }
31
32 function statusInfo(s, a) {
33 var map = {
34 'planned': { label: 'Planned', bg: a.plannedBg, color: a.plannedColor },
35 'in-progress': { label: 'In Progress', bg: a.inProgressBg, color: a.inProgressColor },
36 'done': { label: 'Done', bg: a.doneBg, color: a.doneColor },
37 'declined': { label: 'Declined', bg: a.declinedBg, color: a.declinedColor },
38 'under-review': { label: 'Under Review', bg: a.underReviewBg, color: a.underReviewColor }
39 };
40 return map[s] || map['planned'];
41 }
42
43 function buildBlock(appEl) {
44 if (appEl.dataset.rendered) return;
45 appEl.dataset.rendered = '1';
46
47 var a = Object.assign({
48 boardTitle: 'Feature Requests', description: '', showDescription: true,
49 requests: [], showVotes: true, showCategory: true, showDate: true,
50 fontSize: 14, titleFontSize: 22, cardTitleSize: 16, lineHeight: 160,
51 borderRadius: 12, cardRadius: 10,
52 bgColor: '#f8fafc', cardBg: '#ffffff', borderColor: '#e2e8f0',
53 titleColor: '#0f172a', descColor: '#64748b',
54 cardTitleColor: '#1e293b', cardDescColor: '#64748b',
55 votesBg: '#f1f5f9', votesColor: '#334155',
56 categoryBg: '#f1f5f9', categoryColor: '#475569', dateColor: '#94a3b8',
57 plannedBg: '#dbeafe', plannedColor: '#1e40af',
58 inProgressBg: '#ede9fe', inProgressColor: '#5b21b6',
59 doneBg: '#dcfce7', doneColor: '#14532d',
60 declinedBg: '#fee2e2', declinedColor: '#991b1b',
61 underReviewBg: '#fef9c3', underReviewColor: '#713f12'
62 }, JSON.parse(appEl.dataset.opts || '{}'));
63
64 var lh = (a.lineHeight / 100).toFixed(2);
65 var sorted = a.requests.slice().sort(function (x, y) { return y.votes - x.votes; });
66
67 var wrap = mk('div', 'bkbg-fr-wrap');
68 wrap.style.cssText = 'background:' + a.bgColor + ';border-radius:' + a.borderRadius + 'px;padding:32px';
69 typoCssVarsForEl(a.typoTitle, '--bkbg-fr-tt-', wrap);
70 typoCssVarsForEl(a.typoBody, '--bkbg-fr-bd-', wrap);
71 typoCssVarsForEl(a.typoCardTitle, '--bkbg-fr-ct-', wrap);
72
73 var header = mk('div', 'bkbg-fr-header');
74 var title = tx('h2', 'bkbg-fr-title', a.boardTitle);
75 title.style.color = a.titleColor;
76 ap(header, title);
77 if (a.showDescription && a.description) {
78 var desc = tx('p', 'bkbg-fr-desc', a.description);
79 desc.style.color = a.descColor;
80 ap(header, desc);
81 }
82 ap(wrap, header);
83
84 var grid = mk('div', 'bkbg-fr-grid');
85
86 sorted.forEach(function (req) {
87 var si = statusInfo(req.status, a);
88 var card = mk('div', 'bkbg-fr-card');
89 card.style.cssText = 'background:' + a.cardBg + ';border:1px solid ' + a.borderColor + ';border-radius:' + a.cardRadius + 'px';
90
91 var top = mk('div', 'bkbg-fr-card-top');
92 var info = mk('div', 'bkbg-fr-card-info');
93 var cardTitle = tx('div', 'bkbg-fr-card-title', req.title);
94 cardTitle.style.color = a.cardTitleColor;
95 var cardDesc = tx('div', 'bkbg-fr-card-desc', req.description);
96 cardDesc.style.color = a.cardDescColor;
97 ap(info, cardTitle, cardDesc);
98 ap(top, info);
99
100 if (a.showVotes) {
101 var votes = mk('div', 'bkbg-fr-votes');
102 votes.style.cssText = 'background:' + a.votesBg + ';color:' + a.votesColor;
103 var arr = tx('span', 'bkbg-fr-votes-arrow', '');
104 var cnt = tx('span', null, String(req.votes));
105 ap(votes, arr, cnt);
106 ap(top, votes);
107 }
108 ap(card, top);
109
110 var bottom = mk('div', 'bkbg-fr-card-bottom');
111 var badge = tx('span', 'bkbg-fr-status-badge', si.label);
112 badge.style.cssText = 'background:' + si.bg + ';color:' + si.color;
113 ap(bottom, badge);
114 if (a.showCategory && req.category) {
115 var cat = tx('span', 'bkbg-fr-category', req.category);
116 cat.style.cssText = 'background:' + a.categoryBg + ';color:' + a.categoryColor;
117 ap(bottom, cat);
118 }
119 if (a.showDate && req.date) {
120 var date = tx('span', 'bkbg-fr-date', req.date);
121 date.style.color = a.dateColor;
122 ap(bottom, date);
123 }
124 ap(card, bottom);
125 ap(grid, card);
126 });
127
128 ap(wrap, grid);
129 appEl.innerHTML = '';
130 appEl.appendChild(wrap);
131 }
132
133 function init() { document.querySelectorAll('.bkbg-feature-request-app').forEach(buildBlock); }
134 if (document.readyState !== 'loading') { init(); } else { document.addEventListener('DOMContentLoaded', init); }
135 })();
136