From 10711dd09daeddee84375b8d7663943daba73271 Mon Sep 17 00:00:00 2001 From: Pranav Nachanekar Date: Mon, 9 Sep 2019 15:41:20 +0530 Subject: [PATCH] Refactor UI --- .../crm/doctype/appointment/appointment.json | 8 +- erpnext/www/book-appointment/index.css | 23 ++- erpnext/www/book-appointment/index.html | 85 ++++---- erpnext/www/book-appointment/index.js | 181 +++++++++++------- 4 files changed, 171 insertions(+), 126 deletions(-) diff --git a/erpnext/crm/doctype/appointment/appointment.json b/erpnext/crm/doctype/appointment/appointment.json index ec63420e98..8392549fd3 100644 --- a/erpnext/crm/doctype/appointment/appointment.json +++ b/erpnext/crm/doctype/appointment/appointment.json @@ -28,12 +28,14 @@ { "fieldname": "customer_phone_number", "fieldtype": "Data", - "label": "Phone Number" + "label": "Phone Number", + "reqd": 1 }, { "fieldname": "customer_skype", "fieldtype": "Data", - "label": "Skype ID" + "label": "Skype ID", + "reqd": 1 }, { "fieldname": "customer_details", @@ -48,7 +50,7 @@ "reqd": 1 } ], - "modified": "2019-09-09 12:23:33.611408", + "modified": "2019-09-09 15:40:21.881421", "modified_by": "Administrator", "module": "CRM", "name": "Appointment", diff --git a/erpnext/www/book-appointment/index.css b/erpnext/www/book-appointment/index.css index 3ffe996238..a6e6313f79 100644 --- a/erpnext/www/book-appointment/index.css +++ b/erpnext/www/book-appointment/index.css @@ -1,7 +1,12 @@ .time-slot { - margin: 0 0; + margin-bottom: 2em; + margin-left: 0.5em; + margin-right: 0.5em; + border-radius: 0.4em; + cursor: pointer; border: 0.5px solid #cccccc; - min-height: 100px; + min-height: 75px; + padding: 0.5em 1em; } .time-slot:hover { @@ -9,9 +14,13 @@ } .time-slot.unavailable { - background: #bbb; + background: #CBD5E0; + cursor: not-allowed; + color: #718096 +} - color: #777777 +.time-slot.unavailable .text-muted { + color: #718096 } input[type="radio"] { @@ -22,4 +31,8 @@ input[type="radio"] { .time-slot.selected { color: white; background: #5e64ff; -} \ No newline at end of file +} + +.time-slot.selected .text-muted { + color: #EDF2F7 !important; +} diff --git a/erpnext/www/book-appointment/index.html b/erpnext/www/book-appointment/index.html index b705f9e82d..b915484f54 100644 --- a/erpnext/www/book-appointment/index.html +++ b/erpnext/www/book-appointment/index.html @@ -2,69 +2,60 @@ {% block title %}{{ _("Book Appointment") }}{% endblock %} +{% block script %} + + +{% endblock %} + {% block page_content %}
-
+

Book an appointment

-

Select the date and your timezone

+

Select the date and your timezone

-
-
- - + -
- -
-
-
- - -
-
-

Pick A Time Slot

-

Selected date is Date Span

-
-
-
- -
-
-
-
-
- - -
-
-

Add details

-

Selected date is Date Span at time

+
+
-
- - - - - +
+
+ +
+
+

Add details

+

Selected date is at +

+
+
+
+ + + + + +
+
+
+
{% endblock %} \ No newline at end of file diff --git a/erpnext/www/book-appointment/index.js b/erpnext/www/book-appointment/index.js index e1a2338bfd..bb21ddf273 100644 --- a/erpnext/www/book-appointment/index.js +++ b/erpnext/www/book-appointment/index.js @@ -2,47 +2,35 @@ frappe.ready(() => { initialise_select_date() }) -var holiday_list = []; +window.holiday_list = []; -function navigator(page_no) { - let select_date_div = document.getElementById('select-date'); - select_date_div.style.display = 'none'; - let select_time_div = document.getElementById('select-time'); - select_time_div.style.display = 'none'; - let contact_details_div = document.getElementById('enter-details'); - contact_details_div.style.display = 'none'; - let page; - switch (page_no) { - case 1: page = select_date_div; break; - case 2: page = select_time_div; break; - case 3: page = contact_details_div; break; - } - page.style.display = 'block' +async function initialise_select_date() { + document.getElementById('enter-details').style.display = 'none'; + await get_global_variables(); + setup_date_picker(); + setup_timezone_selector(); + hide_next_button(); } -// Page 1 -async function initialise_select_date() { - navigator(1); - let timezones, settings; - settings = (await frappe.call({ +async function get_global_variables() { + window.appointment_settings = (await frappe.call({ method: 'erpnext.www.book-appointment.index.get_appointment_settings' })).message - timezones = (await frappe.call({ + window.timezones = (await frappe.call({ method: 'erpnext.www.book-appointment.index.get_timezones' })).message; - holiday_list = (await frappe.call({ + window.holiday_list = (await frappe.call({ method: 'erpnext.www.book-appointment.index.get_holiday_list', args: { - 'holiday_list_name': settings.holiday_list + 'holiday_list_name': window.appointment_settings.holiday_list } })).message; - let date_picker = document.getElementById('appointment-date'); - date_picker.max = holiday_list.to_date; - date_picker.min = holiday_list.from_date; - date_picker.value = (new Date()).toISOString().substr(0, 10); +} + +function setup_timezone_selector() { let timezones_element = document.getElementById('appointment-timezone'); var offset = new Date().getTimezoneOffset(); - timezones.forEach(timezone => { + window.timezones.forEach(timezone => { var opt = document.createElement('option'); opt.value = timezone.offset; opt.innerHTML = timezone.timezone_name; @@ -51,56 +39,90 @@ async function initialise_select_date() { }); } -function validate_date() { +function setup_date_picker() { let date_picker = document.getElementById('appointment-date'); - if (date_picker.value === '') { - frappe.throw('Please select a date') - } + let today = new Date(); + date_picker.min = today.toISOString().substr(0, 10); + date_picker.max = window.holiday_list.to_date; } -// Page 2 -async function navigate_to_time_select() { - navigator(2); - timezone = document.getElementById('appointment-timezone').value - date = document.getElementById('appointment-date').value; - var date_spans = document.getElementsByClassName('date-span'); - for (var i = 0; i < date_spans.length; i++) date_spans[i].innerHTML = date; - // date_span.addEventListener('click',initialise_select_date) - // date_span.style.color = '#5e64ff'; - // date_span.style.textDecoration = 'underline'; - // date_span.style.cursor = 'pointer'; - var slots = (await frappe.call({ +function hide_next_button(){ + let next_button = document.getElementById('next-button'); + next_button.disabled = true; + next_button.onclick = ()=>{frappe.msgprint("Please select a date and time")}; +} + +function show_next_button(){ + let next_button = document.getElementById('next-button'); + next_button.disabled = false; + next_button.onclick = setup_details_page; +} + +function on_date_or_timezone_select() { + let date_picker = document.getElementById('appointment-date'); + let timezone = document.getElementById('appointment-timezone'); + if (date_picker.value === '') { + clear_time_slots(); + hide_next_button(); + frappe.throw('Please select a date'); + } + window.selected_date = date_picker.value; + window.selected_timezone = timezone.value; + update_time_slots(date_picker.value, timezone.value); +} + +async function get_time_slots(date, timezone) { + debugger + let slots = (await frappe.call({ method: 'erpnext.www.book-appointment.index.get_appointment_slots', args: { date: date, timezone: timezone } })).message; - let timeslot_container = document.getElementById('timeslot-container'); - console.log(slots) - if (slots.length <= 0) { - let message_div = document.createElement('p'); + return slots; +} +async function update_time_slots(selected_date, selected_timezone) { + let timeslot_container = document.getElementById('timeslot-container'); + window.slots = await get_time_slots(selected_date, selected_timezone); + clear_time_slots(); + if (window.slots.length <= 0) { + let message_div = document.createElement('p'); message_div.innerHTML = "There are no slots available on this date"; timeslot_container.appendChild(message_div); + return } - for (let i = 0; i < slots.length; i++) { - const slot = slots[i]; + window.slots.forEach(slot => { + let start_time = new Date(slot.time) var timeslot_div = document.createElement('div'); timeslot_div.classList.add('time-slot'); timeslot_div.classList.add('col-md'); if (!slot.availability) { timeslot_div.classList.add('unavailable') } - timeslot_div.innerHTML = slot.time.substr(11, 20); + timeslot_div.innerHTML = get_slot_layout(start_time); timeslot_div.id = slot.time.substr(11, 20); + timeslot_div.addEventListener('click', select_time); timeslot_container.appendChild(timeslot_div); + }); + set_default_timeslot(); + show_next_button(); +} + +function clear_time_slots() { + let timeslot_container = document.getElementById('timeslot-container'); + while (timeslot_container.firstChild) { + timeslot_container.removeChild(timeslot_container.firstChild) } - set_default_timeslot() - let time_slot_divs = document.getElementsByClassName('time-slot'); - for (var i = 0; i < time_slot_divs.length; i++) { - time_slot_divs[i].addEventListener('click', select_time); - } +} + +function get_slot_layout(time) { + time = new Date(time) + let start_time_string = moment(time).format("LT"); + let end_time = moment(time).add('1','hours'); + let end_time_string = end_time.format("LT"); + return `${start_time_string}
to ${end_time_string}`; } function select_time() { @@ -110,8 +132,10 @@ function select_time() { try { selected_element = document.getElementsByClassName('selected')[0] } catch (e) { + debugger this.classList.add("selected") } + window.selected_time = this.id selected_element.classList.remove("selected"); this.classList.add("selected"); } @@ -127,23 +151,23 @@ function set_default_timeslot() { } } -function initialise_enter_details() { - navigator(3); - let time_div = document.getElementsByClassName('selected')[0]; - let time_span = document.getElementsByClassName('time-span')[0]; - time_span.innerHTML = time_div.id +function setup_details_page(){ + let page1 = document.getElementById('select-date-time'); + let page2 = document.getElementById('enter-details'); + page1.style.display = 'none'; + page2.style.display = 'block'; + + let date_container = document.getElementsByClassName('date-span')[0]; + let time_container = document.getElementsByClassName('time-span')[0]; + + date_container.innerHTML = new Date(window.selected_date).toLocaleDateString(); + time_container.innerHTML = moment(window.selected_time,"HH:mm:ss").format("LT"); } async function submit() { - var date = document.getElementById('appointment-date').value; - var time = document.getElementsByClassName('selected')[0].id; - contact = {}; - contact.name = document.getElementById('customer_name').value; - contact.number = document.getElementById('customer_number').value; - contact.skype = document.getElementById('customer_skype').value; - contact.notes = document.getElementById('customer_notes').value; - console.log({ date, time, contact }); - let abc = (await frappe.call({ + // form validation here + form_validation(); + let appointment = (await frappe.call({ method: 'erpnext.www.book-appointment.index.create_appointment', args: { 'date': date, @@ -151,5 +175,20 @@ async function submit() { 'contact': contact } })).message; - console.log(abc) + frappe.msgprint(__('Appointment Created Successfully')); + let button = document.getElementById('submit-button'); + button.disabled = true; + button.onclick = () => { console.log('This should never have happened') } } + +function form_validation(){ + var date = window.selected_date; + var time = document.getElementsByClassName('selected')[0].id; + contact = {}; + contact.name = document.getElementById('customer_name').value; + contact.number = document.getElementById('customer_number').value; + contact.skype = document.getElementById('customer_skype').value; + contact.notes = document.getElementById('customer_notes').value; + window.contact = contact + console.log({ date, time, contact }); +}