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 / tax-calculator / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/tax-calculator/frontend.js

184 lines 9.8 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 calcSalesTax(amount, rate) {
5 var tax = amount * (rate / 100);
6 return { net: amount, tax: tax, total: amount + tax };
7 }
8 function calcReverse(total, rate) {
9 var net = total / (1 + rate / 100);
10 return { net: net, tax: total - net, total: total };
11 }
12 function fmt(val, cur, pos) {
13 return pos === 'after' ? val.toFixed(2) + cur : cur + val.toFixed(2);
14 }
15 function esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
16
17 function buildApp(app) {
18 var opts;
19 try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch (e) { return; }
20 var o = opts;
21 var accent = o.accentColor || '#6c3fb5';
22 var cur = o.currency || '$';
23 var pos = o.currencyPos || 'before';
24 var maxW = (o.maxWidth || 580) + 'px';
25 var iRad = (o.inputRadius || 8) + 'px';
26 var cRad = (o.cardRadius || 16) + 'px';
27 var taxLbl = o.taxLabel || 'Sales Tax';
28
29 app.style.paddingTop = (o.paddingTop || 60) + 'px';
30 app.style.paddingBottom = (o.paddingBottom || 60) + 'px';
31 if (o.sectionBg) app.style.background = o.sectionBg;
32
33 /* Header */
34 if (o.showTitle || o.showSubtitle) {
35 var hdr = document.createElement('div');
36 hdr.style.cssText = 'text-align:center;margin-bottom:32px;max-width:' + maxW + ';margin-left:auto;margin-right:auto';
37 if (o.showTitle && o.title) {
38 var ht = document.createElement('h3');
39 ht.className = 'bkbg-tax-title';
40 ht.textContent = o.title;
41 ht.style.cssText = 'color:' + (o.titleColor || '#1e1b4b') + ';margin:0 0 8px';
42 hdr.appendChild(ht);
43 }
44 if (o.showSubtitle && o.subtitle) {
45 var hs = document.createElement('p');
46 hs.textContent = o.subtitle;
47 hs.style.cssText = 'color:' + (o.subtitleColor || '#6b7280') + ';margin:0';
48 hdr.appendChild(hs);
49 }
50 app.appendChild(hdr);
51 }
52
53 /* Card */
54 var card = document.createElement('div');
55 card.style.cssText = 'background:' + (o.cardBg || '#fff') + ';border-radius:' + cRad + ';padding:32px;max-width:' + maxW + ';margin:0 auto;box-shadow:0 4px 24px rgba(0,0,0,0.06)';
56 app.appendChild(card);
57
58 /* State */
59 var mode = o.mode || 'sales';
60 var amount = parseFloat(o.defaultAmount) || 100;
61 var rate = parseFloat(o.defaultRate) || 8.5;
62
63 /* Mode tabs */
64 var modeRow = document.createElement('div');
65 modeRow.style.cssText = 'display:flex;gap:8px;margin-bottom:24px';
66 var modeBtns = {};
67 [['sales','Add Tax →'],['reverse','← Remove Tax']].forEach(function (pair) {
68 var btn = document.createElement('button');
69 btn.className = 'bkbg-tax-mode-btn';
70 btn.textContent = pair[1];
71 btn.style.cssText = 'flex:1;padding:9px;border:none;border-radius:' + iRad + ';font-weight:600;font-size:13px;cursor:pointer';
72 btn.addEventListener('click', function () { mode = pair[0]; refreshMode(); update(); });
73 modeBtns[pair[0]] = btn;
74 modeRow.appendChild(btn);
75 });
76 card.appendChild(modeRow);
77
78 function refreshMode() {
79 Object.keys(modeBtns).forEach(function (k) {
80 modeBtns[k].style.background = k === mode ? accent : (o.statCardBg || '#f9fafb');
81 modeBtns[k].style.color = k === mode ? '#fff' : (o.labelColor || '#374151');
82 amtLabel.textContent = mode === 'reverse' ? 'Total Price (with tax)' : 'Original Amount';
83 });
84 }
85
86 /* Preset chips */
87 if (o.showPresets !== false && (o.presetRates || []).length) {
88 var chipRow = document.createElement('div');
89 chipRow.style.cssText = 'display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px';
90 (o.presetRates || []).forEach(function (p) {
91 var chip = document.createElement('button');
92 chip.className = 'bkbg-tax-preset-chip';
93 chip.textContent = p.label;
94 chip.style.cssText = 'padding:4px 12px;border:1px solid ' + accent + ';border-radius:20px;font-size:12px;font-weight:600;cursor:pointer;background:transparent;color:' + accent;
95 chip.addEventListener('click', function () {
96 rate = p.rate;
97 rateInput.value = rate;
98 update();
99 });
100 chipRow.appendChild(chip);
101 });
102 card.appendChild(chipRow);
103 }
104
105 /* Amount row */
106 var amtLabel, amtInput;
107 (function () {
108 var row = document.createElement('div');
109 row.className = 'bkbg-tax-input-row';
110 amtLabel = document.createElement('label');
111 amtLabel.style.cssText = 'font-size:14px;color:' + (o.labelColor || '#374151');
112 var right = document.createElement('div');
113 right.style.cssText = 'display:flex;align-items:center;gap:6px';
114 var pfx = document.createElement('span');
115 pfx.textContent = cur;
116 pfx.style.cssText = 'color:' + (o.subtitleColor || '#6b7280') + ';font-size:13px';
117 amtInput = document.createElement('input');
118 amtInput.type = 'number'; amtInput.value = amount; amtInput.min = '0'; amtInput.step = '0.01';
119 amtInput.style.cssText = 'width:110px;text-align:right;border:1px solid #d1d5db;border-radius:' + iRad + ';padding:5px 8px;font-size:14px;box-sizing:border-box';
120 amtInput.addEventListener('input', function () { amount = parseFloat(amtInput.value) || 0; update(); });
121 if (pos === 'before') right.appendChild(pfx);
122 right.appendChild(amtInput);
123 if (pos === 'after') right.appendChild(pfx);
124 row.appendChild(amtLabel);
125 row.appendChild(right);
126 card.appendChild(row);
127 })();
128
129 /* Rate row */
130 var rateInput;
131 (function () {
132 var row = document.createElement('div');
133 row.className = 'bkbg-tax-input-row';
134 var lbl = document.createElement('label');
135 lbl.textContent = 'Tax Rate (' + taxLbl + ')';
136 lbl.style.cssText = 'font-size:14px;color:' + (o.labelColor || '#374151');
137 var right = document.createElement('div');
138 right.style.cssText = 'display:flex;align-items:center;gap:6px';
139 rateInput = document.createElement('input');
140 rateInput.type = 'number'; rateInput.value = rate; rateInput.min = '0'; rateInput.step = '0.001';
141 rateInput.style.cssText = 'width:110px;text-align:right;border:1px solid #d1d5db;border-radius:' + iRad + ';padding:5px 8px;font-size:14px;box-sizing:border-box';
142 rateInput.addEventListener('input', function () { rate = parseFloat(rateInput.value) || 0; update(); });
143 var sfx = document.createElement('span');
144 sfx.textContent = '%';
145 sfx.style.cssText = 'color:' + (o.subtitleColor || '#6b7280') + ';font-size:13px';
146 right.appendChild(rateInput);
147 right.appendChild(sfx);
148 row.appendChild(lbl);
149 row.appendChild(right);
150 card.appendChild(row);
151 })();
152
153 /* Result box */
154 var resultBox = document.createElement('div');
155 resultBox.style.cssText = 'background:' + (o.resultBg || '#f5f3ff') + ';border:2px solid ' + (o.resultBorder || '#ede9fe') + ';border-radius:' + cRad + ';padding:20px 24px;margin-top:24px';
156 card.appendChild(resultBox);
157
158 function update() {
159 var res = mode === 'reverse' ? calcReverse(amount, rate) : calcSalesTax(amount, rate);
160 var rs = o.resultSize || 48;
161 resultBox.innerHTML =
162 '<div class="bkbg-tax-result-grid" style="display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px">' +
163 '<div class="bkbg-tax-result-col" style="flex:1;text-align:center;min-width:100px">' +
164 '<div class="bkbg-tax-result-label" style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:' + (o.subtitleColor || '#6b7280') + ';margin-bottom:4px">Net Price</div>' +
165 '<div class="bkbg-tax-result-val" style="font-size:' + (rs * 0.55) + 'px;font-weight:800;color:' + (o.netColor || '#10b981') + '">' + esc(fmt(res.net, cur, pos)) + '</div>' +
166 '</div>' +
167 '<div class="bkbg-tax-result-col" style="flex:1;text-align:center;min-width:100px">' +
168 '<div class="bkbg-tax-result-label" style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:' + (o.subtitleColor || '#6b7280') + ';margin-bottom:4px">' + esc(taxLbl) + '</div>' +
169 '<div class="bkbg-tax-result-val" style="font-size:' + (rs * 0.55) + 'px;font-weight:800;color:' + (o.taxColor || '#ef4444') + '">' + esc(fmt(res.tax, cur, pos)) + '</div>' +
170 '</div>' +
171 '<div class="bkbg-tax-result-col" style="flex:1;text-align:center;min-width:100px">' +
172 '<div class="bkbg-tax-result-label" style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:' + (o.subtitleColor || '#6b7280') + ';margin-bottom:4px">Total Price</div>' +
173 '<div class="bkbg-tax-result-val" style="font-size:' + (rs * 0.7) + 'px;font-weight:900;color:' + (o.totalColor || accent) + '">' + esc(fmt(res.total, cur, pos)) + '</div>' +
174 '</div>' +
175 '</div>';
176 }
177
178 refreshMode();
179 update();
180 }
181
182 document.querySelectorAll('.bkbg-tax-app').forEach(buildApp);
183 })();
184