PluginProbe ʕ •ᴥ•ʔ
Rich Showcase for Google Reviews / 6.4
Rich Showcase for Google Reviews v6.4
6.9.8 6.9.7 6.9.6 trunk 1.4 1.42 1.43 1.44 1.45 1.46 1.47 1.48 1.49 1.5 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.7 1.6.8 1.6.9 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3 2.4 2.4.1 2.4.2 2.5 2.5.1 2.6 2.6.1 2.6.2 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.6.1 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.8.1 4.8.2 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.7.1 5.8 5.9 5.9.1 5.9.2 5.9.3 5.9.7 6.0 6.1 6.2 6.3 6.4 6.4.1 6.5 6.6 6.6.1 6.6.2 6.7 6.8 6.8.1 6.8.2 6.9 6.9.1 6.9.2 6.9.3 6.9.4 6.9.4.1 6.9.4.2 6.9.4.3 6.9.4.4 6.9.5
widget-google-reviews / assets / src / js / admin-main.js
widget-google-reviews / assets / src / js Last commit date
admin-apexcharts.js 3 years ago admin-builder.js 10 months ago admin-main.js 1 year ago public-main.js 1 year ago
admin-main.js
492 lines
1 jQuery(document).ready(function($) {
2
3 $('.grw-admin-page a.nav-tab').on('click', function(e) {
4 var $this = $(this), activeId = $this.attr('href');
5 $(activeId).show().siblings('.tab-content').hide();
6 $this.addClass('nav-tab-active').siblings().removeClass('nav-tab-active');
7 e.preventDefault();
8 });
9
10 /**
11 * Rate us feedback
12 */
13 var $rateus = $('#grw-rate_us');
14 if ($rateus.length) {
15 var $rateus_dlg = $('#grw-rate_us-feedback'),
16 $rateus_stars = $('#grw-rate_us-feedback-stars');
17
18 grw_svg_init();
19 if (window.location.href.indexOf('grw_feed_id=') > -1 && !window['grw_rateus']) {
20 $rateus.addClass('grw-flash-visible');
21 }
22 $('.wp-star', $rateus).click(function() {
23 var rate = $(this).index() + 1;
24 if (rate > 3) {
25 $.post({
26 url : ajaxurl,
27 type : 'POST',
28 dataType : 'json',
29 data : {
30 rate : rate,
31 action : 'grw_rateus_ajax',
32 grw_nonce : $('#grw_nonce').val()
33 },
34 success : function(res) {
35 console.log(res);
36 }
37 });
38 var askUrl = /*(Math.random() * 1).toFixed(0) > 0 ?
39 'https://g.page/r/CZac_S7-Dh2NEBM/review' :*/
40 'https://wordpress.org/support/plugin/widget-google-reviews/reviews/?rate=' + rate + '#new-post';
41 window.open(askUrl, '_blank');
42 grw_rateus_close();
43 } else {
44 $rateus_stars.attr('data-rate', rate);
45 $rateus_stars.html(grw_stars(rate, '#fb8e28', 24));
46 $rateus_dlg.dialog({modal: true, width: '50%', maxWidth: '600px'});
47 $('.ui-widget-overlay').bind('click', function() {
48 $rateus_dlg.dialog('close');
49 });
50 }
51 });
52
53 $('.grw-rate_us-cancel').click(function() {
54 $rateus_dlg.dialog('close');
55 });
56
57 $('.grw-rate_us-send').click(function() {
58 $.post({
59 url : ajaxurl,
60 type : 'POST',
61 dataType : 'json',
62 data : {
63 rate : $rateus_stars.attr('data-rate'),
64 email : $('input', $rateus_dlg).val(),
65 msg : $('textarea', $rateus_dlg).val(),
66 action : 'grw_rateus_ajax_feedback',
67 grw_nonce : $('#grw_nonce').val()
68 },
69 success : function(res) {
70 $rateus_dlg.dialog({'title': 'Feedback sent'})
71 $rateus_dlg.html('<b style="color:#4cc74b">Thank you for your feedback!<br>' +
72 'We received it and will investigate your suggestions.</b>');
73
74 grw_rateus_close();
75 setTimeout(function() {
76 $rateus_dlg.fadeOut(500, function() { $rateus_dlg.dialog('close'); });
77 }, 1500);
78 }
79 });
80 });
81
82 function grw_rateus_close() {
83 setTimeout(function() {
84 $rateus.addClass('grw-flash-gout');
85 $rateus.removeClass('grw-flash-visible');
86 $rateus.removeClass('grw-flash-gout');
87 window['grw_rateus'] = 1;
88 }, 1000);
89 }
90 }
91
92 /**
93 * Overview page
94 */
95 var $overviewRating = $('#grw-overview-rating');
96 if ($overviewRating.length) {
97
98 var MONTHS = 6,
99 $places = $('#grw-overview-places'),
100 $months = $('#grw-overview-months'),
101 $rating = $('#grw-overview-rating'),
102 $reviews = $('#grw-overview-reviews'),
103 chart = null;
104
105 grw_svg_init();
106
107 $places.change(function() {
108 ajax(this.value);
109 });
110
111 $months.change(function() {
112 MONTHS = this.value;
113 ajax($places.val());
114 });
115
116 ajax(0, function(res) {
117 /*
118 * Places select filled
119 */
120 $.each(res.places, function(i, place) {
121 $places.append($('<option>', {
122 value: place.id,
123 text : place.name
124 }));
125 });
126 });
127
128 function ajax(pid, cb) {
129 var data = {
130 action : 'grw_overview_ajax',
131 grw_nonce : jQuery('#grw_nonce').val()
132 };
133
134 if (pid) {
135 data.place_id = pid;
136 }
137 jQuery.post({
138 url : ajaxurl,
139 type : 'POST',
140 dataType : 'json',
141 data : data,
142 success : function(res) {
143
144 var place = res.places.length > 1 ? res.places.find(x => x.id == pid) : res.places[0];
145
146 /*
147 * Stats minmax grouping and calculate result
148 */
149 var stats_result = null;
150
151 if (res.stats_minmax.length) {
152
153 let minmax = {},
154 mintime = 0,
155 nowtime = (new Date().getTime() / 1000).toFixed(0);
156
157 for (let i = 0; i < res.stats_minmax.length; i++) {
158
159 let mm = res.stats_minmax[i],
160 gpid = mm.google_place_id;
161
162 mintime = !mintime || mm.time < mintime ? mm.time : mintime;
163
164 if (minmax[gpid]) {
165
166 minmax[gpid] = {
167 time : parseInt(nowtime - minmax[gpid].time),
168 rating : parseFloat((mm.rating - minmax[gpid].rating).toFixed(1)),
169 review_count : parseInt(mm.review_count - minmax[gpid].review_count)
170 };
171
172 if (stats_result) {
173 stats_result = {
174 time : minmax[gpid].time,
175 rating : stats_result.rating + minmax[gpid].rating,
176 review_count : stats_result.review_count + minmax[gpid].review_count
177 }
178 } else {
179 stats_result = minmax[gpid];
180 }
181
182 delete minmax[gpid];
183
184 } else {
185 minmax[gpid] = {
186 time : mintime,
187 rating : mm.rating,
188 review_count : mm.review_count
189 };
190 }
191
192 }
193 }
194
195 let $stats = $('#grw-overview-stats');
196 $stats.html('Not calculated yet');
197
198 if (stats_result) {
199 let sr = stats_result.rating,
200 src = stats_result.review_count;
201 $stats.html(
202 '<div class="grw-overview-h">While using the plugin</div>' +
203 '<div>' +
204 'Usage time: ' +
205 '<span class="grw-stat-val grw-stat-up">' + grw_s2dmy(stats_result.time) + '</span>' +
206 '</div>' +
207 '<div>' +
208 'Rating up: ' +
209 '<span class="grw-stat-val grw-stat-' + (sr < 0 ? 'down' : (sr > 0 ? 'up' : '')) + '">' + sr + '</span>' +
210 '</div>' +
211 '<div>' +
212 'Reviews up: ' +
213 '<span class="grw-stat-val grw-stat-' + (src < 0 ? 'down' : (src > 0 ? 'up' : '')) + '">' + src + '</span>' +
214 '</div>'
215 );
216 }
217
218 /*
219 * Render rating
220 */
221 $rating.html(
222 '<div class="wp-gr">' +
223 '<div class="grw-overview-h">' + place.name + '</div>' +
224 '<div>' +
225 '<span class="wp-google-rating">' + res.rating + '</span>' +
226 '<span class="wp-google-stars">' + grw_stars(res.rating, '#fb8e28', 20) + '</span>' +
227 '</div>' +
228 '<div class="wp-google-powered">Based on ' + res.review_count + ' reviews</div>' +
229
230 (place.updated ?
231 '<div class="wp-google-powered">Last updated: ' +
232 '<span class="wp-google-time">' +
233 rpi.Time.getTime(parseInt(place.updated), rpi.Utils.lang(), 'ago') +
234 '</span>' +
235 '</div>' : '') +
236 '</div>'
237 );
238
239 /*
240 * Render reviews
241 */
242 var list = '',
243 common = rpi.Common($reviews[0], {text_size: 50}, {
244 time : 'wp-google-time',
245 text : 'wp-google-text',
246 readmore : 'wp-more-toggle'
247 });
248
249 $.each(res.reviews, function(i, review) {
250 list += grw_review(review);
251 });
252 $reviews.html(
253 '<div class="wp-gr wpac">' +
254 '<div class="wp-google-reviews">' + list + '</div>' +
255 '</div>'
256 );
257 common.init();
258
259 $('.wp-review-hide', $reviews).unbind('click').click(function() {
260 grw_review_hide($(this));
261 return false;
262 });
263
264 /*
265 * Render stats
266 */
267
268 // 1) Grouped by Google place ID
269 var gs = {};
270 for (var s = 0; s < res.stats.length; s++) {
271 var stat = res.stats[s],
272 gpi = stat.google_place_id;
273
274 gs[gpi] = gs[gpi] || [];
275 gs[gpi].push({
276 time: parseInt(stat.time),
277 rating: parseFloat(stat.rating),
278 review_count: parseInt(stat.review_count)
279 });
280 }
281
282 // 2) Calculate how many months needs
283 var period = parseInt((res.stats[0].time - res.stats[res.stats.length - 1].time) / (60 * 60 * 24 * 30)),
284 months = period > 4 ? MONTHS : (period || 1);
285
286 // 2) Calculate stats by months (last six)
287 var ms = {},
288 today = new Date();
289
290 for (var i = 0; i < months; i++) {
291 var startDay = new Date(today.getFullYear(), today.getMonth() - i, 1),
292 endTime = new Date(today.getFullYear(), today.getMonth() + 1 - i, 0).getTime(),
293 month = startDay.toLocaleString('default', {month: 'short'}) + ' ' + startDay.getFullYear().toString().slice(-2);
294
295 ms[month] = ms[month] || {};
296
297 for (g in gs) {
298 var j = 0, xx = gs[g];
299
300 do {
301 var stat = xx[j++],
302 time = stat.time * 1000;
303
304 ms[month][g] = ms[month][g] || {};
305 ms[month][g].count = parseInt(stat.review_count);
306
307 } while(time > endTime && j < xx.length);
308 }
309 }
310
311 // 3) Summary and normalize
312 var cat = [], data = [], series = []; var ttt = {};
313 for (m in ms) {
314 var count = 0;
315 for (p in ms[m]) {
316 count += ms[m][p].count;
317
318 // --- TEMP ---
319 var pp = res.places.find(x => x.id == p)
320 ttt[pp.name] = ttt[pp.name] || {};
321 ttt[pp.name].data = ttt[pp.name].data || [];
322 ttt[pp.name].data.unshift(ms[m][p].count);
323 // --- TEMP ---
324
325 }
326 cat.unshift(m);
327 data.unshift(count);
328 }
329
330 // --- TEMP ---
331 for (tt in ttt) {
332 series.push({name: tt, data: ttt[tt].data});
333 }
334 // --- TEMP ---
335
336 // 4) Render chart
337 var options = {
338 series: [{
339 name: 'Reviews',
340 data: data
341 }],
342 chart: {
343 height: 350,
344 type: 'bar',
345 //stacked: true,
346 },
347 plotOptions: {
348 bar: {
349 dataLabels: {
350 position: 'top', // top, center, bottom
351 },
352 }
353 },
354 dataLabels: {
355 enabled: true,
356 offsetY: -20,
357 style: {
358 fontSize: '12px',
359 colors: ["#304758"]
360 }
361 },
362 tooltip: {
363 enabled: true,
364 intersect: false,
365 custom: function() { return ''; }
366 },
367 xaxis: {
368 categories: cat,
369 axisBorder: {
370 show: false
371 },
372 axisTicks: {
373 show: false
374 },
375 tooltip: {
376 enabled: true
377 }
378 },
379 yaxis: {
380 axisBorder: {
381 show: false
382 },
383 axisTicks: {
384 show: false,
385 }
386 },
387 title: {
388 text: 'Monthly reviews count',
389 align: 'center',
390 style: {
391 color: '#444'
392 }
393 }
394 };
395
396 if (chart) {
397 chart.updateOptions({series: [{name: 'Reviews', data: data}], xaxis: {categories: cat}});
398 } else {
399 chart = new ApexCharts(document.querySelector('#chart'), options);
400 chart.render();
401 }
402
403 cb && cb(res);
404 }
405 });
406 }
407 }
408
409 });
410
411 function grw_svg_init() {
412 var span = document.createElement('span');
413 span.style.display = 'none';
414 span.innerHTML = grw_svg();
415 document.body.appendChild(span);
416 }
417
418 function grw_svg() {
419 return '' +
420 '<svg>' +
421 '<defs>' +
422 '<g id="rp-star" width="17" height="17">' +
423 '<path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z"></path>' +
424 '</g>' +
425 '<g id="rp-star-half" width="17" height="17">' +
426 '<path d="M1250 957l257-250-356-52-66-10-30-60-159-322v963l59 31 318 168-60-355-12-66zm452-262l-363 354 86 500q5 33-6 51.5t-34 18.5q-17 0-40-12l-449-236-449 236q-23 12-40 12-23 0-34-18.5t-6-51.5l86-500-364-354q-32-32-23-59.5t54-34.5l502-73 225-455q20-41 49-41 28 0 49 41l225 455 502 73q45 7 54 34.5t-24 59.5z"></path>' +
427 '</g>' +
428 '<g id="rp-star-o" width="17" height="17">' +
429 '<path d="M1201 1004l306-297-422-62-189-382-189 382-422 62 306 297-73 421 378-199 377 199zm527-357q0 22-26 48l-363 354 86 500q1 7 1 20 0 50-41 50-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#ccc"></path>' +
430 '</g>' +
431 '<g id="rp-logo-g" height="44" width="44" fill="none" fill-rule="evenodd">' +
432 '<path d="M482.56 261.36c0-16.73-1.5-32.83-4.29-48.27H256v91.29h127.01c-5.47 29.5-22.1 54.49-47.09 71.23v59.21h76.27c44.63-41.09 70.37-101.59 70.37-173.46z" fill="#4285f4"></path><path d="M256 492c63.72 0 117.14-21.13 156.19-57.18l-76.27-59.21c-21.13 14.16-48.17 22.53-79.92 22.53-61.47 0-113.49-41.51-132.05-97.3H45.1v61.15c38.83 77.13 118.64 130.01 210.9 130.01z" fill="#34a853"></path><path d="M123.95 300.84c-4.72-14.16-7.4-29.29-7.4-44.84s2.68-30.68 7.4-44.84V150.01H45.1C29.12 181.87 20 217.92 20 256c0 38.08 9.12 74.13 25.1 105.99l78.85-61.15z" fill="#fbbc05"></path><path d="M256 113.86c34.65 0 65.76 11.91 90.22 35.29l67.69-67.69C373.03 43.39 319.61 20 256 20c-92.25 0-172.07 52.89-210.9 130.01l78.85 61.15c18.56-55.78 70.59-97.3 132.05-97.3z" fill="#ea4335"></path><path d="M20 20h472v472H20V20z"></path>' +
433 '</g>' +
434 '</defs>' +
435 '</svg>';
436 }
437
438 function grw_stars(rating, color, size) {
439 var str = '';
440 for (var i = 1; i < 6; i++) {
441 var score = rating - i;
442 if (score >= 0) {
443 str += grw_star('', color, size);
444 } else if (score > -1 && score < 0) {
445 if (score < -0.75) {
446 str += grw_star('-o', '#ccc', size);
447 } else if (score > -0.25) {
448 str += grw_star('', color, size);
449 } else {
450 str += grw_star('-half', color, size);
451 }
452 } else {
453 str += grw_star('-o', '#ccc', size);
454 }
455 }
456 return str;
457 }
458
459 function grw_star(prefix, color, size) {
460 return '' +
461 '<span class="wp-star">' +
462 '<svg viewBox="0 0 1792 1792" width="' + size + '" height="' + size + '">' +
463 '<use xlink:href="#rp-star' + prefix + '" fill="' + color + '"/>' +
464 '</svg>' +
465 '</span>';
466 }
467
468 function grw_review(review) {
469 return '' +
470 '<div class="wp-google-review' + (review.hide == '' ? '' : ' wp-review-hidden') + '">' +
471 '<div class="wp-google-right">' +
472 '<a href="' + review.author_url + '" class="wp-google-name" target="_blank" rel="nofollow noopener">' + review.author_name + '</a>' +
473 '<div class="wp-google-time" data-time="' + review.time + '"></div>' +
474 '<div class="wp-google-feedback">' +
475 '<span class="wp-google-stars">' + grw_stars(review.rating, '#fb8e28', 16) + '</span>' +
476 '<span class="wp-google-text">' + review.text + '</span>' +
477 '</div>' +
478 '<a href="#" class="wp-review-hide" data-id="' + review.id + '">' + (review.hide == '' ? 'Hide' : 'Show') + ' review</a>' +
479 '</div>' +
480 '</div>';
481 }
482
483 function grw_s2dmy(s) {
484 let d = (s / (60 * 60 * 24)).toFixed(0);
485 if (d > 30) {
486 if (d > 365) {
487 return Math.round(d / 365) + ' years';
488 }
489 return Math.round(d / 30) + ' months';
490 }
491 return d + ' days';
492 }