From eb12d6e5f89b3718ac676ab6cefb21f4fdbc04a5 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 11 Jul 2019 17:49:39 +1000 Subject: [PATCH] rating start works now --- css/bts_timesheet.css | 43 ++++++- html/job.html | 24 ++-- js/bts_timesheet.js | 282 ++++++++++++++++++++++++++++++++++++++++-- ts.php | 45 ++++++- 4 files changed, 369 insertions(+), 25 deletions(-) diff --git a/css/bts_timesheet.css b/css/bts_timesheet.css index 3bb35c4..07563fa 100644 --- a/css/bts_timesheet.css +++ b/css/bts_timesheet.css @@ -8,6 +8,14 @@ body { z-index: -1; } +.blink_me { + animation: blinker 0.3s linear infinite; +} + +@keyframes blinker { + 50% { opacity: 0; } +} + .titlebar_gradient { /* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#f6e6b4+0,ed9017+100 */ background: rgb(246,230,180); /* Old browsers */ @@ -17,6 +25,14 @@ body { filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6e6b4', endColorstr='#ed9017',GradientType=0 ); /* IE6-9 */ } + +.sheettitle h1:hover{ + text-decoration: underline; + font-weight: bolder; + cursor: pointer; + animation: blinker 1s linear infinite; +} + .timesheets { width: calc(100vw - 300px); height: 100vh; @@ -673,13 +689,15 @@ div.brate, div.bstaff, div.bclient, div.bconfirmed, +div.bsave, +div.brating, div.bdelete { width: 10%; height: 30px; } div.btos { - width: 20%; + width: 15%; } div.brate{ @@ -693,11 +711,34 @@ div.brate{ div.bdelete, +div.bsave, div.bconfirmed { text-align:center; width: 5%; } +div.brating{ + text-align: center; + cursor: pointer; +} + + +.brating { + unicode-bidi: bidi-override; + direction: rtl; +} +.brating > span:hover:before, +.brating > span:hover ~ span:before { + content: "\2605"; + position: absolute; +} + + +div.bsave.saved span{ + display: none; +} + + /* short code for the table */ div.btos select, div.bstart input, diff --git a/html/job.html b/html/job.html index ec58727..7369381 100644 --- a/html/job.html +++ b/html/job.html @@ -3,26 +3,28 @@
- + [bts_type_of_service]
[bts_rate_options]
[bts_select_staff]
[bts_select_client]
-
+
+
+ + + + + +
+
+ +
+
\ No newline at end of file diff --git a/js/bts_timesheet.js b/js/bts_timesheet.js index b5cf5d3..15da342 100644 --- a/js/bts_timesheet.js +++ b/js/bts_timesheet.js @@ -254,8 +254,28 @@ jQuery('div.workspace').append(this.el); this.load_data(data); dtp_init(); + this.init_start_rating(); } + init_start_rating(){ + var self = this; + this.el.find("div.brating span").click(function(){ + var r = $(this).attr('data-rating'); + self.set_rating(r); + }) + + this.el.find("div.brating").mouseenter(function(){ + //change to all hollow star + $(this).find('span').html('☆'); + }); + + this.el.find("div.brating").mouseleave(function(){ + self.set_rating(self.data.rating); + }); + + } + + load_data(data) { this.set_job_id(data.id); @@ -347,6 +367,27 @@ return; return this.el.find('div.bconfirmed input').prop('checked', val!=0); } + get_rating(){ + var count =0; + this.el.find('div.brating span').each(function(i,e){ + if ($(e).html()=='★') + count +=1; + }); + return count; + } + set_rating(num){ + if (!(1 <= num && num <=5)) + return; + this.data.rating=num; + this.el.find('div.brating span').each(function(i,e){ + var rating = $(e).attr('data-rating'); + var rating = parseInt(rating); + if (rating <= num) + $(e).html('★'); + else + $(e).html('☆'); + }); + } get_record_from_ui(){ var record = {}; @@ -410,19 +451,240 @@ $(s).trigger('click'); } - setTimeout(function(){ - set_modal_title('warning', 'suck title'); - set_modal_content('warning', 'fucking details'); - open_modal('warning'); - }, 1000); +// setTimeout(function(){ +// set_modal_title('warning', 'suck title'); +// set_modal_content('warning', 'fucking details'); +// //open_modal('warning'); +// }, 1000); +// +// setTimeout(function(){ +// set_modal_title('error', 'error title'); +// set_modal_content('error', 'error details'); +// //open_modal('error'); +// }, 5000); + + $(document).on('mouseenter', 'div.week1 div', function(){ + $(this).addClass('blink_me'); + get_week2_partner(this).addClass('blink_me'); + }); + $(document).on('mouseleave', 'div.week1 div', function(){ + $(this).removeClass('blink_me'); + get_week2_partner(this).removeClass('blink_me'); + }); + + function get_week2_partner(div){ + var index = $(div).index()+1; + return $('div.week2 div:nth-child('+index+')'); + } + + function init_weekdays(){ + var curr = new Date; // get current date + // First day is the day of the month - the day of the week + var first = curr.getDate() - curr.getDay() + 1; //+1 we want Mon as first + var last = first + 6; // last day is the first day + 6 + + //var firstday = new Date(curr.setDate(first)); //Mon + //var lastday = new Date(curr.setDate(last)); //Sun + + var pos = 1; //first lot + for (var i=first; i<=last; i++) + { + var d1 = new Date(curr.setDate(i)); + var d2 = new Date(curr.setDate(i+7)); + set_day_number(1,pos, d1); //week 1 + set_day_number(2,pos, d2); //week 2 + pos +=1; + } + } + + function set_day_number(week, index, date){ + var selector = 'span[name="w'+week+'d'+index+'"]'; + $(selector).html(date.getDate()); + $(selector).data({date:date}); + } + + function format_date(date) { + var monthNames = [ + "January", "February", "March", + "April", "May", "June", "July", + "August", "September", "October", + "November", "December" + ]; + + var day = date.getDate(); + var monthIndex = date.getMonth(); + var year = date.getFullYear(); + + return day + ' ' + monthNames[monthIndex] + ' ' + year; + } + function set_today(){ + var selector = 'div.sheettitle span[name="today"]'; + var curr = new Date; + $(selector).html(format_date(curr)); + } + + Date.prototype.get_week_number = function(){ + var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate())); + var dayNum = d.getUTCDay() || 7; + d.setUTCDate(d.getUTCDate() + 4 - dayNum); + var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1)); + return Math.ceil((((d - yearStart) / 86400000) + 1)/7) + }; + + function set_week_number(){ + var date = $('span[name="w1d1"]').data().date; + console.log("date %o", date); + var num = date.get_week_number(); + $('div.weekly span[name="week1"]').html(num); + $('div.weekly span[name="week2"]').html(num+1); + } + + $('div.prevweek.left').click(function(){ + $('div.weekdays span.weekday').each(function(i, e){ + var date = $(e).data().date; + var newdate = new Date(date.setDate(date.getDate() -7 )); + $(e).html(newdate.getDate()); + $(e).data({data:newdate}); + }); + set_week_number(); + load_timesheet(); + }); + $('div.nextweek.right').click(function(){ + $('div.weekdays span.weekday').each(function(i, e){ + var date = $(e).data().date; + var newdate = new Date(date.setDate(date.getDate() +7 )); + $(e).html(newdate.getDate()); + $(e).data({data:newdate}); + }); + set_week_number(); + load_timesheet(); + }); + + $('div.weekly div.weekname.prev').click(function(){ + if (!confirm ('copy entire week to next week? ')) + return; + }); + + $('div.weekly div.weekname.next').click(function(){ + if (!confirm ('copy entire week to previous week? ')) + return; + }); + + $('div.week1 > div').click(function(){ + if (!confirm ('copy to next week')) + return; + }); + + $('div.sheettitle h1').click(function(){ + reset_title_to_today(); + }) + + function reset_title_to_today(){ + set_today(); + init_weekdays(); + set_week_number(); + load_timesheet(); + } + + + function load_timesheet() + { + clear_workspace(); + var first = $('span[name="w1d1"]').data().date; + var last = $('span[name="w2d7"]').data().date; + $.post(bts().ajax_url, { // POST request + _ajax_nonce: bts().nonce, // nonce + action: "list_job", // action + start: format_date(first), + finish: format_date(last), + }, function(response, status, xhr){ + if (response.status =='success'){ + response.jobs.forEach(function(job){ + new Job(job); + }); + //filter it if reqired + do_filter_workspace(); + }else{ + alert('error loading job'); + } + }); + + } + + function format_date(date){ + var dd = date.getDate(); + var mm = date.getMonth() + 1; //January is 0! - setTimeout(function(){ - set_modal_title('error', 'error title'); - set_modal_content('error', 'error details'); - open_modal('error'); - }, 5000); + var yyyy = date.getFullYear(); + if (dd < 10) { + dd = '0' + dd; + } + if (mm < 10) { + mm = '0' + mm; + } + return yyyy + '-' + mm + '-' +dd ; + } + function clear_workspace()//clear all timesheet jobs + { + $('div.workspace > div.divTable').remove(); + //clear datetime picker + $('div.xdsoft_datetimepicker').remove(); + } + + $('button[name="confirmschedule"]').click(function(){ + $('span.ticon.ticon-save').trigger('click'); + }); + + + $(document).on('click','div.userlist', debounce(do_filter_workspace)); + + function do_filter_workspace(){ + var staffs =[]; + $('div.stafflist div.peopleitem :checked').each(function(i, e){ + var id = $(e).parent().attr('data-id'); + //console.log("%o, id=%s", e, id); + staffs.push(id.substring(1)); + }); + + var clients =[]; + $('div.clientlist div.peopleitem :checked').each(function(i, e){ + var id = $(e).parent().attr('data-id'); + //console.log("%o, id=%s", e, id); + clients.push(id.substring(1)); + }); + + console.log('staffs %o' , staffs); + console.log('clients %o' , clients); + + filter_workspace(staffs, clients); + } + + function filter_workspace(staffs, clients){ + + //if both array is empty + if( (staffs === undefined || staffs.length ==0) && + (clients===undefined || clients.length ==0)){ + //show all + $('div.workspace div.divTable').show(); + return; + } + + //filter some of them; + $('div.workspace div.divTable').each(function(i,e){ + var job = $(e).data().job; + var s = job.get_staff(); + var c = job.get_client(); + + if (staffs.indexOf(s) ==-1 && clients.indexOf(c) ==-1) + $(this).fadeOut(); + else + $(this).fadeIn(); + }); + } + + reset_title_to_today(); /*________________________________________________________________________*/ }); })(jQuery); diff --git a/ts.php b/ts.php index 668c101..0575558 100644 --- a/ts.php +++ b/ts.php @@ -41,6 +41,8 @@ class AcareOffice{ add_shortcode( 'bts_rate_options', array($this, 'bts_rate_options')); add_shortcode( 'bts_select_staff', array($this, 'bts_select_staff')); add_shortcode( 'bts_select_client', array($this, 'bts_select_client')); + add_shortcode( 'bts_type_of_service', array($this, 'bts_type_of_service')); + add_action('wp_ajax_list_staff', array($this,'list_staff' )); add_action('wp_ajax_list_client', array($this,'list_client' )); @@ -227,6 +229,21 @@ class AcareOffice{ return $result; } + public function bts_type_of_service($attr){ + $result = ' + '; + return $result; + } + //generate template based on html file private function template($id, $file) { @@ -411,12 +428,34 @@ class AcareOffice{ //ajax browse job with different filters function list_job(){ check_ajax_referer('acaresydney'); - $r = $_POST['record']; - $response = array(); + $start = $_POST['start']; + $finish = $_POST['finish']; + $response = array( + 'status'=>'success', + 'jobs' => [], + ); + + $sql = "SELECT * FROM $this->table_name WHERE start>='%s' and start <='%s'"; + $jobs = $this->db->get_results($this->db->prepare ($sql, array($start, $finish))); + + if (! empty($jobs)){ + $response['status'] = 'success'; + foreach( $jobs as $s){ + $response['jobs'][] = array( + 'id' => $s->id, + 'tos' => $s->tos, + 'start'=> $s->start, + 'finish'=> $s->finish, + 'rate'=> $s->rate, + 'staff'=> $s->staff, + 'client'=> $s->client, + 'ack' => $s->ack, + ); + } + } wp_send_json($response); wp_die(); } - } $bb = new AcareOffice();