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

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

300 lines 15.4 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 || 'px';
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); el.style.setProperty(prefix + 'letter-spacing', 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); el.style.setProperty(prefix + 'word-spacing', 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 var DAYS_OF_WEEK = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
30 var ZODIAC = [
31 { sign:'Capricorn', symbol:'', end:[1,19] },
32 { sign:'Aquarius', symbol:'', end:[2,18] },
33 { sign:'Pisces', symbol:'', end:[3,20] },
34 { sign:'Aries', symbol:'', end:[4,19] },
35 { sign:'Taurus', symbol:'', end:[5,20] },
36 { sign:'Gemini', symbol:'', end:[6,20] },
37 { sign:'Cancer', symbol:'', end:[7,22] },
38 { sign:'Leo', symbol:'', end:[8,22] },
39 { sign:'Virgo', symbol:'', end:[9,22] },
40 { sign:'Libra', symbol:'', end:[10,22] },
41 { sign:'Scorpio', symbol:'', end:[11,21] },
42 { sign:'Sagittarius',symbol:'', end:[12,21] },
43 { sign:'Capricorn', symbol:'', end:[12,31] },
44 ];
45
46 function getZodiac(month, day) {
47 for (var i = 0; i < ZODIAC.length; i++) {
48 var z = ZODIAC[i];
49 if (month < z.end[0] || (month === z.end[0] && day <= z.end[1])) return z;
50 }
51 return ZODIAC[ZODIAC.length - 1];
52 }
53
54 function calcAge(birthDate, now) {
55 var years = now.getFullYear() - birthDate.getFullYear();
56 var months = now.getMonth() - birthDate.getMonth();
57 var days = now.getDate() - birthDate.getDate();
58 if (days < 0) {
59 months--;
60 var prevMonth = new Date(now.getFullYear(), now.getMonth(), 0);
61 days += prevMonth.getDate();
62 }
63 if (months < 0) { years--; months += 12; }
64 var totalDays = Math.floor((now - birthDate) / 86400000);
65 return { years: years, months: months, days: days, totalDays: totalDays };
66 }
67
68 function daysUntilBirthday(birthDate, now) {
69 var next = new Date(now.getFullYear(), birthDate.getMonth(), birthDate.getDate());
70 if (next < now) next.setFullYear(now.getFullYear() + 1);
71 return Math.ceil((next - now) / 86400000);
72 }
73
74 function fmt(n) { return n.toLocaleString('en-US'); }
75
76 function buildApp(app) {
77 var opts = {};
78 try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch (e) {}
79
80 var accent = opts.accentColor || '#6c3fb5';
81 var cardBg = opts.cardBg || '#ffffff';
82 var ageCardBg = opts.ageCardBg || accent;
83 var ageCardClr= opts.ageCardColor || '#ffffff';
84 var resultBg = opts.resultBg || '#f5f3ff';
85 var resultBdr = opts.resultBorder || '#ede9fe';
86 var statsBg = opts.statsBg || '#fafafa';
87 var statsBdr = opts.statsBorder || '#e5e7eb';
88 var titleClr = opts.titleColor || '#1e1b4b';
89 var subClr = opts.subtitleColor || '#6b7280';
90 var labelClr = opts.labelColor || '#374151';
91 var cRadius = (opts.cardRadius !== undefined ? opts.cardRadius : 16) + 'px';
92 var aRadius = (opts.ageCardRadius !== undefined ? opts.ageCardRadius : 12) + 'px';
93 var maxW = (opts.maxWidth || 680) + 'px';
94 var ptop = (opts.paddingTop !== undefined ? opts.paddingTop : 60) + 'px';
95 var pbot = (opts.paddingBottom!== undefined ? opts.paddingBottom : 60) + 'px';
96 var titleSz = (opts.titleSize || 28) + 'px';
97 var ageNumSz = (opts.ageNumSize || 52) + 'px';
98
99 /* Card */
100 var card = document.createElement('div');
101 card.className = 'bkbg-age-card';
102 card.style.cssText = [
103 'background:' + cardBg,
104 'border-radius:' + cRadius,
105 'padding-top:' + ptop,
106 'padding-bottom:' + pbot,
107 'padding-left:32px',
108 'padding-right:32px',
109 'max-width:' + maxW,
110 'margin:0 auto',
111 ].join(';');
112 app.innerHTML = '';
113 app.appendChild(card);
114
115 /* Typography CSS vars */
116 app.style.setProperty('--bkbg-age-title-sz', titleSz);
117 app.style.setProperty('--bkbg-age-num-sz', ageNumSz);
118 typoCssVarsForEl(opts.titleTypo, '--bkbg-age-title-', app);
119 typoCssVarsForEl(opts.ageNumTypo, '--bkbg-age-num-', app);
120
121 /* Title */
122 if (opts.showTitle !== false && opts.title) {
123 var h2 = document.createElement('h2');
124 h2.className = 'bkbg-age-title';
125 h2.style.cssText = 'color:' + titleClr + ';text-align:center;margin-top:0;margin-bottom:8px;font-weight:800';
126 h2.textContent = opts.title;
127 card.appendChild(h2);
128 }
129
130 /* Subtitle */
131 if (opts.showSubtitle !== false && opts.subtitle) {
132 var sub = document.createElement('p');
133 sub.style.cssText = 'color:' + subClr + ';text-align:center;margin-top:0;margin-bottom:28px';
134 sub.textContent = opts.subtitle;
135 card.appendChild(sub);
136 }
137
138 /* Date input */
139 var dateField = document.createElement('div');
140 dateField.className = 'bkbg-age-date-field';
141 var dateLabel = document.createElement('label');
142 dateLabel.className = 'bkbg-age-date-label';
143 dateLabel.style.color = labelClr;
144 dateLabel.textContent = 'Date of Birth';
145 var dateInput = document.createElement('input');
146 dateInput.type = 'date';
147 dateInput.className = 'bkbg-age-date-input';
148 dateInput.max = new Date().toISOString().slice(0, 10);
149 dateField.appendChild(dateLabel);
150 dateField.appendChild(dateInput);
151 card.appendChild(dateField);
152
153 /* Results area (hidden until date chosen) */
154 var resultsDiv = document.createElement('div');
155 card.appendChild(resultsDiv);
156
157 /* Empty state */
158 var emptyDiv = document.createElement('div');
159 emptyDiv.className = 'bkbg-age-empty';
160 emptyDiv.textContent = 'Enter your birth date above to see your age';
161 card.appendChild(emptyDiv);
162
163 function render() {
164 var val = dateInput.value;
165 if (!val) { resultsDiv.innerHTML = ''; emptyDiv.style.display = 'block'; return; }
166
167 var now = new Date();
168 now.setHours(0,0,0,0);
169 var birthDate = new Date(val);
170 if (isNaN(birthDate.getTime()) || birthDate >= now) { resultsDiv.innerHTML = ''; emptyDiv.style.display = 'block'; return; }
171
172 emptyDiv.style.display = 'none';
173 resultsDiv.innerHTML = '';
174
175 var age = calcAge(birthDate, now);
176 var untilBd= daysUntilBirthday(birthDate, now);
177 var zodiac = getZodiac(birthDate.getMonth() + 1, birthDate.getDate());
178 var bornDay= DAYS_OF_WEEK[birthDate.getDay()];
179
180 /* Age cards */
181 if (opts.showAgeCards !== false) {
182 var ageCards = document.createElement('div');
183 ageCards.className = 'bkbg-age-cards';
184 ageCards.style.marginBottom = '20px';
185 [
186 { val: age.years, label: opts.yearsLabel || 'Years' },
187 { val: age.months, label: opts.monthsLabel || 'Months' },
188 { val: age.days, label: opts.daysLabel || 'Days' },
189 ].forEach(function (item) {
190 var ci = document.createElement('div');
191 ci.className = 'bkbg-age-card-item';
192 ci.style.cssText = 'background:' + ageCardBg + ';border-radius:' + aRadius;
193 var numEl = document.createElement('div');
194 numEl.className = 'bkbg-age-num';
195 numEl.style.cssText = 'color:' + ageCardClr;
196 numEl.textContent = item.val;
197 var lblEl = document.createElement('div');
198 lblEl.className = 'bkbg-age-card-label';
199 lblEl.style.color = ageCardClr;
200 lblEl.textContent = item.label;
201 ci.appendChild(numEl);
202 ci.appendChild(lblEl);
203 ageCards.appendChild(ci);
204 });
205 resultsDiv.appendChild(ageCards);
206 }
207
208 /* Birthday countdown */
209 if (opts.showNextBirthday !== false) {
210 var bdDiv = document.createElement('div');
211 bdDiv.className = 'bkbg-age-birthday';
212 bdDiv.style.cssText = 'background:' + resultBg + ';border:1.5px solid ' + resultBdr;
213 var bdEmoji = document.createElement('span');
214 bdEmoji.className = 'bkbg-age-birthday-emoji';
215 bdEmoji.textContent = '🎂';
216 var bdInfo = document.createElement('div');
217 var bdMain = document.createElement('div');
218 bdMain.className = 'bkbg-age-birthday-main';
219 bdMain.style.color = titleClr;
220 bdMain.textContent = untilBd === 0 ? '🎉 Happy Birthday!' : ('Next birthday in ' + untilBd + ' days');
221 var bdSub = document.createElement('div');
222 bdSub.className = 'bkbg-age-birthday-sub';
223 bdSub.style.color = subClr;
224 bdSub.textContent = 'Turning ' + (age.years + 1) + ' soon';
225 bdInfo.appendChild(bdMain);
226 bdInfo.appendChild(bdSub);
227 bdDiv.appendChild(bdEmoji);
228 bdDiv.appendChild(bdInfo);
229 resultsDiv.appendChild(bdDiv);
230 }
231
232 /* Zodiac + born day */
233 var metaCount = (opts.showZodiac !== false ? 1 : 0) + (opts.showBornDay !== false ? 1 : 0);
234 if (metaCount > 0) {
235 var metaDiv = document.createElement('div');
236 metaDiv.className = 'bkbg-age-meta' + (metaCount === 2 ? ' two-col' : '');
237 metaDiv.style.marginBottom = '14px';
238 if (opts.showZodiac !== false) {
239 var zEl = document.createElement('div');
240 zEl.className = 'bkbg-age-meta-item';
241 zEl.style.cssText = 'background:' + statsBg + ';border:1px solid ' + statsBdr;
242 zEl.innerHTML = '<div class="bkbg-age-meta-label" style="color:' + subClr + '">Zodiac Sign</div>' +
243 '<div class="bkbg-age-meta-value" style="color:' + titleClr + '">' + zodiac.symbol + ' ' + zodiac.sign + '</div>';
244 metaDiv.appendChild(zEl);
245 }
246 if (opts.showBornDay !== false) {
247 var bdayEl = document.createElement('div');
248 bdayEl.className = 'bkbg-age-meta-item';
249 bdayEl.style.cssText = 'background:' + statsBg + ';border:1px solid ' + statsBdr;
250 bdayEl.innerHTML = '<div class="bkbg-age-meta-label" style="color:' + subClr + '">Born On</div>' +
251 '<div class="bkbg-age-meta-value" style="color:' + titleClr + '">�
252 ' + bornDay + '</div>';
253 metaDiv.appendChild(bdayEl);
254 }
255 resultsDiv.appendChild(metaDiv);
256 }
257
258 /* Life stats */
259 if (opts.showLifeStats !== false) {
260 var statsDiv = document.createElement('div');
261 statsDiv.className = 'bkbg-age-stats';
262 statsDiv.style.cssText = 'background:' + statsBg + ';border:1px solid ' + statsBdr;
263 var statsHead = document.createElement('div');
264 statsHead.className = 'bkbg-age-stats-heading';
265 statsHead.style.color = subClr;
266 statsHead.textContent = 'Life Stats';
267 statsDiv.appendChild(statsHead);
268 var grid = document.createElement('div');
269 grid.className = 'bkbg-age-stats-grid';
270 [
271 { label:'Total Days', val: fmt(age.totalDays) },
272 { label:'Total Weeks', val: fmt(Math.floor(age.totalDays / 7)) },
273 { label:'Total Hours', val: fmt(age.totalDays * 24) },
274 { label:'Heartbeats (est.)', val: fmt(age.totalDays * 24 * 60 * 72) },
275 ].forEach(function (s) {
276 var si = document.createElement('div');
277 var sl = document.createElement('div');
278 sl.className = 'bkbg-age-stat-label';
279 sl.style.color = subClr;
280 sl.textContent = s.label;
281 var sv = document.createElement('div');
282 sv.className = 'bkbg-age-stat-value';
283 sv.style.color = accent;
284 sv.textContent = s.val;
285 si.appendChild(sl);
286 si.appendChild(sv);
287 grid.appendChild(si);
288 });
289 statsDiv.appendChild(grid);
290 resultsDiv.appendChild(statsDiv);
291 }
292 }
293
294 dateInput.addEventListener('change', render);
295 render();
296 }
297
298 document.querySelectorAll('.bkbg-age-app').forEach(buildApp);
299 })();
300