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

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

256 lines 11.1 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 var ACTIVITY_FACTOR = { sedentary: 30, light: 33, moderate: 35, active: 38, very_active: 42 };
5 var CLIMATE_FACTOR = { temperate: 0, hot: 500, cold: -200 };
6
7 function calcWater(weightKg, activity, climate) {
8 var base = weightKg * (ACTIVITY_FACTOR[activity] || 35);
9 base += (CLIMATE_FACTOR[climate] || 0);
10 return Math.max(500, base);
11 }
12
13 function getTips(activity, climate) {
14 var list = [
15 'Drink a glass of water first thing in the morning.',
16 'Carry a reusable water bottle throughout the day.'
17 ];
18 if (activity === 'active' || activity === 'very_active') {
19 list.push('Drink 500 ml extra for every hour of intense exercise.');
20 }
21 if (climate === 'hot') list.push('Hot climates increase sweat loss — drink more frequently.');
22 if (climate === 'cold') list.push('Cold weather can reduce thirst sensation — stay mindful of drinking.');
23 list.push('Herbal teas and water-rich foods count toward your daily intake.');
24 return list;
25 }
26
27 function init(app) {
28 var a;
29 try { a = JSON.parse(app.getAttribute('data-opts')); } catch (e) { return; }
30
31 var accent = a.accentColor || '#3b82f6';
32
33 app.style.paddingTop = (a.paddingTop || 60) + 'px';
34 app.style.paddingBottom = (a.paddingBottom || 60) + 'px';
35 if (a.sectionBg) app.style.background = a.sectionBg;
36 app.innerHTML = '';
37
38 var wrap = document.createElement('div');
39 wrap.className = 'bkbg-wic-wrap';
40 wrap.style.maxWidth = (a.maxWidth || 500) + 'px';
41 wrap.style.borderRadius = (a.cardRadius || 16) + 'px';
42 wrap.style.background = a.cardBg || '#fff';
43 app.appendChild(wrap);
44
45 if (a.showTitle || a.showSubtitle) {
46 var header = document.createElement('div');
47 header.className = 'bkbg-wic-header';
48 if (a.showTitle && a.title) {
49 var title = document.createElement('div');
50 title.className = 'bkbg-wic-title';
51 title.textContent = a.title;
52 if (a.titleColor) title.style.color = a.titleColor;
53 header.appendChild(title);
54 }
55 if (a.showSubtitle && a.subtitle) {
56 var sub = document.createElement('div');
57 sub.className = 'bkbg-wic-subtitle';
58 sub.textContent = a.subtitle;
59 if (a.subtitleColor) sub.style.color = a.subtitleColor;
60 header.appendChild(sub);
61 }
62 wrap.appendChild(header);
63 }
64
65 var ir = (a.inputRadius || 8) + 'px';
66 var ib = '1.5px solid ' + (a.inputBorder || '#e5e7eb');
67 var currentUnit = a.defaultUnit || 'kg';
68
69 // Weight field
70 var weightField = document.createElement('div');
71 weightField.className = 'bkbg-wic-field';
72
73 var weightLabelRow = document.createElement('div');
74 weightLabelRow.className = 'bkbg-wic-label';
75 if (a.labelColor) weightLabelRow.style.color = a.labelColor;
76
77 var weightLabelSpan = document.createElement('span');
78 weightLabelSpan.textContent = 'Body Weight';
79
80 var unitToggle = document.createElement('div');
81 unitToggle.className = 'bkbg-wic-unit-toggle';
82
83 ['kg','lbs'].forEach(function(u) {
84 var btn = document.createElement('button');
85 btn.className = 'bkbg-wic-unit-btn';
86 btn.textContent = u;
87 btn.dataset.unit = u;
88 btn.style.background = u === currentUnit ? accent : '#e5e7eb';
89 btn.style.color = u === currentUnit ? '#fff' : '#374151';
90 btn.addEventListener('click', function() {
91 var old = currentUnit;
92 currentUnit = u;
93 var cur = parseFloat(weightInput.value) || 0;
94 if (old === 'kg' && u === 'lbs') weightInput.value = (cur * 2.20462).toFixed(1);
95 else if (old === 'lbs' && u === 'kg') weightInput.value = (cur * 0.453592).toFixed(1);
96 unitToggle.querySelectorAll('.bkbg-wic-unit-btn').forEach(function(b) {
97 var active = b.dataset.unit === currentUnit;
98 b.style.background = active ? accent : '#e5e7eb';
99 b.style.color = active ? '#fff' : '#374151';
100 });
101 recalculate();
102 });
103 unitToggle.appendChild(btn);
104 });
105
106 weightLabelRow.appendChild(weightLabelSpan);
107 weightLabelRow.appendChild(unitToggle);
108 weightField.appendChild(weightLabelRow);
109
110 var weightInput = document.createElement('input');
111 weightInput.type = 'number';
112 weightInput.className = 'bkbg-wic-input';
113 weightInput.value = String(a.defaultWeight || 70);
114 weightInput.min = '1';
115 weightInput.style.borderRadius = ir;
116 weightInput.style.border = ib;
117 weightInput.addEventListener('input', recalculate);
118 weightField.appendChild(weightInput);
119 wrap.appendChild(weightField);
120
121 function makeSelect(labelText, options, defaultVal) {
122 var field = document.createElement('div');
123 field.className = 'bkbg-wic-field';
124 var lbl = document.createElement('div');
125 lbl.className = 'bkbg-wic-label';
126 lbl.textContent = labelText;
127 if (a.labelColor) lbl.style.color = a.labelColor;
128 var sel = document.createElement('select');
129 sel.className = 'bkbg-wic-select';
130 sel.style.borderRadius = ir;
131 sel.style.border = ib;
132 options.forEach(function(o) {
133 var opt = document.createElement('option');
134 opt.value = o[0];
135 opt.textContent = o[1];
136 if (o[0] === defaultVal) opt.selected = true;
137 sel.appendChild(opt);
138 });
139 sel.addEventListener('change', recalculate);
140 field.appendChild(lbl);
141 field.appendChild(sel);
142 wrap.appendChild(field);
143 return sel;
144 }
145
146 var actSel = makeSelect('Activity Level', [
147 ['sedentary', 'Sedentary (little or no exercise)'],
148 ['light', 'Light (light exercise 1-3 days/wk)'],
149 ['moderate', 'Moderate (exercise 3-5 days/wk)'],
150 ['active', 'Active (hard exercise 6-7 days/wk)'],
151 ['very_active','Very Active (athlete / physical job)']
152 ], a.defaultActivity || 'moderate');
153
154 var climSel = makeSelect('Climate', [
155 ['temperate','Temperate (cool/mild climate)'],
156 ['hot', 'Hot / Humid Climate'],
157 ['cold', 'Cold / Dry Climate']
158 ], a.defaultClimate || 'temperate');
159
160 // Result card
161 var resultCard = document.createElement('div');
162 resultCard.className = 'bkbg-wic-result';
163 resultCard.style.background = a.resultBg || accent;
164 resultCard.style.borderRadius = ir;
165
166 var resultLbl = document.createElement('div'); resultLbl.className = 'bkbg-wic-result-label'; resultLbl.style.color = a.resultColor||'#fff'; resultLbl.textContent = 'Daily Water Recommendation';
167 var resultMain = document.createElement('div'); resultMain.className = 'bkbg-wic-result-main'; resultMain.style.color = a.resultColor||'#fff'; resultMain.style.fontSize = (a.resultSize||56)+'px';
168 var resultSub = document.createElement('div'); resultSub.className = 'bkbg-wic-result-sub'; resultSub.style.color = a.resultColor||'#fff';
169 resultCard.appendChild(resultLbl); resultCard.appendChild(resultMain); resultCard.appendChild(resultSub);
170 wrap.appendChild(resultCard);
171
172 // Glasses
173 var glassesEl = null;
174 if (a.showGlasses) {
175 glassesEl = document.createElement('div');
176 glassesEl.className = 'bkbg-wic-glasses';
177 glassesEl.style.background = a.glassBg || '#eff6ff';
178 glassesEl.style.borderRadius = ir;
179 wrap.appendChild(glassesEl);
180 }
181
182 // Tips
183 var tipsEl = null;
184 if (a.showTips) {
185 tipsEl = document.createElement('div');
186 tipsEl.className = 'bkbg-wic-tips';
187 tipsEl.style.background = a.tipsBg || '#f0fdf4';
188 tipsEl.style.borderColor = a.tipsBorder || '#bbf7d0';
189 tipsEl.style.borderRadius = ir;
190 wrap.appendChild(tipsEl);
191 }
192
193 function recalculate() {
194 var wt = parseFloat(weightInput.value) || (a.defaultWeight || 70);
195 var activity= actSel.value;
196 var climate = climSel.value;
197 var wKg = currentUnit === 'lbs' ? wt * 0.453592 : wt;
198 var ml = calcWater(wKg, activity, climate);
199 var liters = (ml / 1000).toFixed(1);
200 var oz = Math.round(ml / 29.574);
201 var glasses = Math.round(ml / (a.glassSize || 250));
202
203 resultMain.textContent = liters + ' L';
204 resultSub.textContent = oz + ' fl oz · ' + Math.round(ml) + ' ml';
205
206 if (glassesEl) {
207 glassesEl.innerHTML = '';
208 var glLbl = document.createElement('div');
209 glLbl.className = 'bkbg-wic-glasses-label';
210 glLbl.style.color = a.glassColor || accent;
211 glLbl.textContent = '= ' + glasses + ' glasses of ' + (a.glassSize || 250) + ' ml';
212 var glRow = document.createElement('div');
213 glRow.className = 'bkbg-wic-glasses-row';
214 var limit = Math.min(glasses, 16);
215 for (var i = 0; i < limit; i++) {
216 var ico = document.createElement('span');
217 ico.className = 'bkbg-wic-glass-icon';
218 ico.textContent = '💧';
219 glRow.appendChild(ico);
220 }
221 if (glasses > 16) {
222 var more = document.createElement('span');
223 more.className = 'bkbg-wic-glass-more';
224 more.style.color = a.glassColor || accent;
225 more.textContent = '+' + (glasses - 16) + ' more';
226 glRow.appendChild(more);
227 }
228 glassesEl.appendChild(glLbl);
229 glassesEl.appendChild(glRow);
230 }
231
232 if (tipsEl) {
233 tipsEl.innerHTML = '';
234 var tipHead = document.createElement('div');
235 tipHead.className = 'bkbg-wic-tips-heading';
236 tipHead.style.color = a.tipsColor || '#166534';
237 tipHead.textContent = '💡 Hydration Tips';
238 var ul = document.createElement('ul');
239 ul.className = 'bkbg-wic-tips-list';
240 getTips(activity, climate).forEach(function(tip) {
241 var li = document.createElement('li');
242 li.textContent = tip;
243 li.style.color = a.tipsColor || '#166534';
244 ul.appendChild(li);
245 });
246 tipsEl.appendChild(tipHead);
247 tipsEl.appendChild(ul);
248 }
249 }
250
251 recalculate();
252 }
253
254 document.querySelectorAll('.bkbg-wic-app').forEach(init);
255 })();
256