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 / date-difference / frontend.js

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

249 lines 13.5 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) return;
6 if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif");
7 if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight);
8 if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform);
9 if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style);
10 if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration);
11 var su = typo.sizeUnit || 'px';
12 if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
13 if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
14 if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
15 var lhu = typo.lineHeightUnit || '';
16 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
17 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
18 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
19 var lsu = typo.letterSpacingUnit || 'px';
20 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu);
21 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
22 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
23 var wsu = typo.wordSpacingUnit || 'px';
24 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu);
25 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
26 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
27 }
28
29 function diffDates(from, to) {
30 var d1 = new Date(from), d2 = new Date(to);
31 if (isNaN(d1) || isNaN(d2)) return null;
32 var swapped = false;
33 if (d1 > d2) { var t = d1; d1 = d2; d2 = t; swapped = true; }
34 var totalMs = d2 - d1;
35 var totalDays = Math.floor(totalMs / 86400000);
36 var totalWeeks = Math.floor(totalDays / 7);
37 var totalHours = Math.floor(totalMs / 3600000);
38 var totalMins = Math.floor(totalMs / 60000);
39
40 /* Calendar years/months/days */
41 var y = d2.getFullYear() - d1.getFullYear();
42 var m = d2.getMonth() - d1.getMonth();
43 var d = d2.getDate() - d1.getDate();
44 if (d < 0) { m--; var prev = new Date(d2.getFullYear(), d2.getMonth(), 0); d += prev.getDate(); }
45 if (m < 0) { y--; m += 12; }
46
47 /* Working days */
48 var wdays = 0, cur = new Date(d1);
49 while (cur < d2) { var dow = cur.getDay(); if (dow !== 0 && dow !== 6) wdays++; cur.setDate(cur.getDate()+1); }
50
51 return { years:y, months:m, days:d, totalDays:totalDays, totalWeeks:totalWeeks, totalHours:totalHours, totalMins:totalMins, workingDays:wdays, swapped:swapped };
52 }
53
54 function todayStr() {
55 var d = new Date(), month = d.getMonth()+1, day = d.getDate();
56 return d.getFullYear() + '-' + (month<10?'0'+month:month) + '-' + (day<10?'0'+day:day);
57 }
58
59 function buildApp(app) {
60 var opts = {};
61 try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch (e) {}
62
63 var accent = opts.accentColor || '#6c3fb5';
64 var cardBg = opts.cardBg || '#ffffff';
65 var resultBg = opts.resultBg || '#f5f3ff';
66 var resultBdr= opts.resultBorder || '#ede9fe';
67 var cRadius = (opts.cardRadius || 16) + 'px';
68 var iRadius = (opts.inputRadius || 8) + 'px';
69 var maxW = (opts.maxWidth || 620) + 'px';
70 var ptop = (opts.paddingTop || 60) + 'px';
71 var pbot = (opts.paddingBottom|| 60) + 'px';
72 var numSz = (opts.numSize || 40) + 'px';
73 var titleSz = (opts.titleSize || 26) + 'px';
74 var lclr = opts.labelColor || '#374151';
75
76 var state = { from: todayStr(), to: todayStr() };
77
78 /* Set typography CSS vars on wrapper */
79 app.style.setProperty('--bkbg-dd-ttl-fs', titleSz);
80 app.style.setProperty('--bkbg-dd-sub-fs', '14px');
81 app.style.setProperty('--bkbg-dd-num-fs', numSz);
82 typoCssVarsForEl(opts.typoTitle, '--bkbg-dd-ttl-', app);
83 typoCssVarsForEl(opts.typoSubtitle, '--bkbg-dd-sub-', app);
84 typoCssVarsForEl(opts.typoNumber, '--bkbg-dd-num-', app);
85
86 /* Card */
87 var card = document.createElement('div');
88 card.className = 'bkbg-dd-card';
89 card.style.cssText = 'background:' + cardBg + ';border-radius:' + cRadius + ';max-width:' + maxW + ';margin:0 auto;padding:' + ptop + ' 32px ' + pbot;
90 app.innerHTML = '';
91 app.appendChild(card);
92
93 /* Title */
94 if (opts.showTitle !== false && opts.title) {
95 var h2 = document.createElement('h2');
96 h2.className = 'bkbg-dd-title';
97 h2.style.cssText = 'color:' + (opts.titleColor||'#1e1b4b');
98 h2.textContent = opts.title;
99 card.appendChild(h2);
100 }
101 if (opts.showSubtitle !== false && opts.subtitle) {
102 var sub = document.createElement('p');
103 sub.className = 'bkbg-dd-subtitle';
104 sub.style.cssText = 'color:' + (opts.subtitleColor||'#6b7280');
105 sub.textContent = opts.subtitle;
106 card.appendChild(sub);
107 }
108
109 var inpCSS = 'width:100%;padding:10px 12px;border:1.5px solid #e5e7eb;border-radius:' + iRadius + ';font-size:15px;box-sizing:border-box;outline:none;background:#fff;color:' + lclr;
110
111 /* Date pickers row */
112 var pickers = document.createElement('div');
113 pickers.className = 'bkbg-dd-pickers';
114 pickers.style.cssText = 'display:flex;gap:12px;align-items:flex-end;margin-bottom:20px;flex-wrap:wrap';
115
116 function mkPicker(labelTxt, val, onCh) {
117 var col = document.createElement('div');
118 col.style.cssText = 'flex:1;min-width:120px';
119 var lbl = document.createElement('label');
120 lbl.className = 'bkbg-dd-label';
121 lbl.style.cssText = 'font-size:13px;font-weight:600;color:' + lclr + ';display:block;margin-bottom:4px';
122 lbl.textContent = labelTxt;
123 var inp = document.createElement('input');
124 inp.type = 'date'; inp.value = val; inp.className = 'bkbg-dd-input'; inp.style.cssText = inpCSS;
125 inp.addEventListener('change', function () { onCh(inp.value); });
126 col.appendChild(lbl); col.appendChild(inp);
127 return { col: col, inp: inp };
128 }
129
130 var fromPicker = mkPicker(opts.labelFrom || 'From Date', state.from, function (v) { state.from = v; update(); });
131 var toPicker = mkPicker(opts.labelTo || 'To Date', state.to, function (v) { state.to = v; update(); });
132
133 pickers.appendChild(fromPicker.col);
134
135 if (opts.showSwapBtn !== false) {
136 var swapBtn = document.createElement('button');
137 swapBtn.className = 'bkbg-dd-swap';
138 swapBtn.style.cssText = 'padding:10px 14px;border:1.5px solid ' + accent + ';border-radius:' + iRadius + ';background:#fff;color:' + accent + ';cursor:pointer;font-weight:600;font-size:18px;flex-shrink:0';
139 swapBtn.textContent = '';
140 swapBtn.title = 'Swap dates';
141 swapBtn.addEventListener('click', function () {
142 var tmp = state.from;
143 state.from = state.to;
144 state.to = tmp;
145 fromPicker.inp.value = state.from;
146 toPicker.inp.value = state.to;
147 update();
148 });
149 pickers.appendChild(swapBtn);
150 }
151
152 pickers.appendChild(toPicker.col);
153 card.appendChild(pickers);
154
155 /* Results area */
156 var resultsArea = document.createElement('div');
157 card.appendChild(resultsArea);
158
159 /* Stat configs */
160 function getStats(diff) {
161 var list = [];
162 if (opts.showTotalDays !== false) list.push({ label:'Total Days', val:diff.totalDays.toLocaleString(), unit:'days', color:opts.daysColor ||'#3b82f6' });
163 if (opts.showWeeks !== false) list.push({ label:'Total Weeks', val:diff.totalWeeks.toLocaleString(), unit:'weeks', color:opts.weeksColor ||'#10b981' });
164 if (opts.showHours !== false) list.push({ label:'Total Hours', val:diff.totalHours.toLocaleString(), unit:'hours', color:opts.hoursColor ||'#f59e0b' });
165 if (opts.showMinutes !== false) list.push({ label:'Total Minutes', val:diff.totalMins.toLocaleString(), unit:'minutes', color:'#8b5cf6' });
166 if (opts.showWorkingDays !== false) list.push({ label:'Working Days', val:diff.workingDays.toLocaleString(),unit:'Mon–Fri', color:opts.wdaysColor ||'#ef4444' });
167 return list;
168 }
169
170 function update() {
171 resultsArea.innerHTML = '';
172 var diff = diffDates(state.from, state.to);
173 var sameDay = state.from === state.to;
174
175 if (!diff || sameDay) {
176 var empty = document.createElement('div');
177 empty.className = 'bkbg-dd-empty';
178 empty.style.cssText = 'text-align:center;padding:32px;color:#9ca3af;background:' + resultBg + ';border-radius:' + cRadius + ';border:1.5px solid ' + resultBdr;
179 empty.textContent = 'Select two different dates to see the difference.';
180 resultsArea.appendChild(empty);
181 return;
182 }
183
184 /* YMD summary */
185 if (opts.showYMD !== false) {
186 var box = document.createElement('div');
187 box.className = 'bkbg-dd-result-box';
188 box.style.cssText = 'background:' + resultBg + ';border:1.5px solid ' + resultBdr + ';border-radius:' + cRadius + ';padding:20px;text-align:center;margin-bottom:16px';
189
190 var rlbl = document.createElement('div');
191 rlbl.className = 'bkbg-dd-result-label';
192 rlbl.style.cssText = 'font-size:13px;color:#9ca3af;text-transform:uppercase;letter-spacing:0.06em;margin-bottom:8px';
193 rlbl.textContent = 'Duration';
194 box.appendChild(rlbl);
195
196 var ymdParts = [];
197 if (diff.years > 0) ymdParts.push(diff.years + ' yr');
198 if (diff.months > 0) ymdParts.push(diff.months + ' mo');
199 if (diff.days > 0) ymdParts.push(diff.days + ' day');
200 if (ymdParts.length === 0) ymdParts.push('0 days');
201
202 var ymdEl = document.createElement('div');
203 ymdEl.className = 'bkbg-dd-ymd';
204 ymdEl.style.cssText = 'font-size:22px;font-weight:800;color:' + (opts.ymdColor||accent) + ';line-height:1.3';
205 ymdEl.textContent = ymdParts.join(' ');
206 box.appendChild(ymdEl);
207
208 if (diff.swapped) {
209 var note = document.createElement('div');
210 note.className = 'bkbg-dd-swapped-note';
211 note.style.cssText = 'font-size:12px;color:#9ca3af;margin-top:8px';
212 note.textContent = '(dates swapped — showing absolute difference)';
213 box.appendChild(note);
214 }
215
216 resultsArea.appendChild(box);
217 }
218
219 /* Stat cards */
220 var stats = getStats(diff);
221 if (stats.length > 0) {
222 var cols = stats.length <= 2 ? '1fr '.repeat(stats.length).trim()
223 : stats.length <= 4 ? '1fr 1fr'
224 : '1fr 1fr 1fr';
225
226 var grid = document.createElement('div');
227 grid.className = 'bkbg-dd-stats';
228 grid.style.cssText = 'display:grid;grid-template-columns:' + cols + ';gap:10px';
229
230 stats.forEach(function (s) {
231 var sc = document.createElement('div');
232 sc.className = 'bkbg-dd-stat';
233 sc.style.cssText = 'text-align:center;background:#fff;border-radius:10px;padding:16px 8px;border:1.5px solid #e5e7eb';
234 sc.innerHTML = '<div class="bkbg-dd-stat-label" style="font-size:' + (opts.statLabelFontSize || 11) + 'px;text-transform:uppercase;letter-spacing:0.05em;color:#9ca3af;margin-bottom:4px">' + s.label + '</div>' +
235 '<div class="bkbg-dd-stat-num" style="color:' + s.color + '">' + s.val + '</div>' +
236 '<div class="bkbg-dd-stat-unit" style="font-size:' + (opts.statUnitFontSize || 12) + 'px;color:#9ca3af">' + s.unit + '</div>';
237 grid.appendChild(sc);
238 });
239
240 resultsArea.appendChild(grid);
241 }
242 }
243
244 update();
245 }
246
247 document.querySelectorAll('.bkbg-dd-app').forEach(buildApp);
248 })();
249