From 88cc9f1574c8f6d0d3c388f17c599877748199b8 Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Mon, 5 Oct 2015 00:31:06 +0200 Subject: [PATCH] UI fixes for the app. --- src/application/views/backend/customers.php | 276 ++--- src/application/views/backend/services.php | 386 +++--- src/application/views/backend/settings.php | 2 +- src/application/views/backend/users.php | 1208 +++++++++---------- src/assets/css/backend.css | 7 +- src/assets/js/general_functions.js | 120 +- src/assets/js/installation.js | 16 +- src/assets/js/working_plan.js | 139 ++- 8 files changed, 1081 insertions(+), 1073 deletions(-) diff --git a/src/application/views/backend/customers.php b/src/application/views/backend/customers.php index b7266726..58fcc1a2 100644 --- a/src/application/views/backend/customers.php +++ b/src/application/views/backend/customers.php @@ -1,138 +1,138 @@ - - - - - - -
-
-
-
- - - -
- -

lang->line('customers'); ?>

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

lang->line('details'); ?>

- - -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- lang->line('fields_are_required'); ?>
-
- -
-

lang->line('appointments'); ?>

-
-
-
-
-
-
\ No newline at end of file + + + + + + +
+
+
+
+ + + +
+ +

lang->line('customers'); ?>

+
+
+ +
+
+
+ + + + + + + + + + + +
+ + +
+ + + +
+

lang->line('details'); ?>

+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ lang->line('fields_are_required'); ?>
+
+ +
+

lang->line('appointments'); ?>

+
+
+
+
+
+
diff --git a/src/application/views/backend/services.php b/src/application/views/backend/services.php index 5e8c8eb4..2f5f3327 100644 --- a/src/application/views/backend/services.php +++ b/src/application/views/backend/services.php @@ -1,192 +1,194 @@ - - - - -
- - - -
- -
-
- - - -
- -

lang->line('services'); ?>

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

lang->line('details'); ?>

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

- - lang->line('fields_are_required'); ?> -
-
- - - -
\ No newline at end of file + + + + +
+ + + +
+ +
+
+
+ + + +
+ +

lang->line('services'); ?>

+
+
+ +
+
+
+ + + +
+ + +
+ +

lang->line('details'); ?>

+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +

+ + lang->line('fields_are_required'); ?> +
+
+
+ + + +
diff --git a/src/application/views/backend/settings.php b/src/application/views/backend/settings.php index 016d367f..f9653b53 100644 --- a/src/application/views/backend/settings.php +++ b/src/application/views/backend/settings.php @@ -376,7 +376,7 @@ // -------------------------------------------------------------- ?>
-

Easy!Appointments

+

Easy!Appointments

lang->line('about_ea_info'); ?>

diff --git a/src/application/views/backend/users.php b/src/application/views/backend/users.php index d1ad70dd..a9cdbb02 100644 --- a/src/application/views/backend/users.php +++ b/src/application/views/backend/users.php @@ -1,604 +1,604 @@ - - - - - - - - - - - - - -
- - - - - -
-
-
- - - -
- -

lang->line('admins'); ?>

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

lang->line('details'); ?>

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

lang->line('admins'); ?>

+
+
+ +
+
+
+ + + +
+ + +
+ +

lang->line('details'); ?>

+ + + + + +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ + + + + + +
diff --git a/src/assets/css/backend.css b/src/assets/css/backend.css index 0a311ce2..cc3266fe 100644 --- a/src/assets/css/backend.css +++ b/src/assets/css/backend.css @@ -289,14 +289,15 @@ body .jspTrack { #existing-customers-list div { display: inline-block; width: 250px; - margin: 0 5px 5px 0; - padding: 3px 5px; + margin: 0 7px 7px 0; + padding: 5px; border-radius: 3px; } #existing-customers-list div:hover { - background: #B8F0C1; + background: #3DD481; font-weight: bold; + color: #FFF; cursor: pointer; } diff --git a/src/assets/js/general_functions.js b/src/assets/js/general_functions.js index 179cf971..a3a81761 100644 --- a/src/assets/js/general_functions.js +++ b/src/assets/js/general_functions.js @@ -1,19 +1,19 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** * This file contains the General Functions javascript namespace. - * It contains functions that apply both on the front and back + * It contains functions that apply both on the front and back * end of the application. - * + * * @namespace GeneralFunctions */ var GeneralFunctions = { @@ -24,26 +24,26 @@ var GeneralFunctions = { EXCEPTIONS_MESSAGE: EALang['unexpected_issues_message'], WARNINGS_TITLE: EALang['unexpected_warnings'], WARNINGS_MESSAGE: EALang['unexpected_warnings_message'], - + /** * This functions displays a message box in * the admin array. It is usefull when user * decisions or verifications are needed. - * + * * @param {string} title The title of the message box. * @param {string} message The message of the dialog. - * @param {array} messageButtons Contains the dialog + * @param {array} messageButtons Contains the dialog * buttons along with their functions. */ displayMessageBox: function(title, message, messageButtons) { // Check arguments integrity. if (title == undefined || title == '') { title = ''; - } + } if (message == undefined || message == '') { message = ''; - } + } if (messageButtons == undefined) { messageButtons = {}; @@ -61,7 +61,7 @@ var GeneralFunctions = { '
' + '

' + message + '

' + '
' - ); + ); $("#message_box").dialog({ autoOpen: false, @@ -74,16 +74,16 @@ var GeneralFunctions = { closeOnEscape: true }); - $('#message_box').dialog('open'); - $('.ui-dialog .ui-dialog-buttonset button').addClass('btn'); + $('#message_box').dialog('open'); + $('.ui-dialog .ui-dialog-buttonset button').addClass('btn btn-default'); $('#message_box .ui-dialog-titlebar-close').hide(); }, /** * This method centers a DOM element vertically and horizontally * on the page. - * - * @param {object} elementHandle The object that is going to be + * + * @param {object} elementHandle The object that is going to be * centered. */ centerElementOnPage: function(elementHandle) { @@ -97,19 +97,19 @@ var GeneralFunctions = { position: 'absolute', left: elementLeft, top: elementTop - }); + }); }); $(window).resize(); }, /** - * This function retrieves a parameter from a "GET" formed url. - * + * This function retrieves a parameter from a "GET" formed url. + * * @link http://www.netlobo.com/url_query_string_javascript.html - * + * * @param {string} url The selected url. * @param {string} name The parameter name. - * @returns {String} Returns the parameter value. + * @returns {String} Returns the parameter value. */ getUrlParameter: function(url, parameterName) { parameterName = parameterName.replace(/[\[]/,'\\\[').replace(/[\]]/,'\\\]'); @@ -125,7 +125,7 @@ var GeneralFunctions = { /** * This function creates a RFC 3339 date string. This string is needed * by the Google Calendar API in order to pass dates as parameters. - * + * * @param {date} dt The given date that will be transformed * @returns {String} Returns the transformed string. */ @@ -139,20 +139,20 @@ var GeneralFunctions = { + pad(dt.getUTCMinutes())+':' + pad(dt.getUTCSeconds())+'Z'; }, - + /** - * This method creates and returns an exact copy of the provided object. + * This method creates and returns an exact copy of the provided object. * It is very usefull whenever changes need to be made to an object without * modyfing the original data. - * + * * @link http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object - * + * * @param {object} originalObject Object to be copied. * @returns {object} Returns an exact copy of the provided element. */ clone: function(originalObject) { // Handle the 3 simple types, and null or undefined - if (null == originalObject || 'object' != typeof originalObject) + if (null == originalObject || 'object' != typeof originalObject) return originalObject; // Handle Date @@ -175,7 +175,7 @@ var GeneralFunctions = { if (originalObject instanceof Object) { var copy = {}; for (var attr in originalObject) { - if (originalObject.hasOwnProperty(attr)) + if (originalObject.hasOwnProperty(attr)) copy[attr] = GeneralFunctions.clone(originalObject[attr]); } return copy; @@ -183,11 +183,11 @@ var GeneralFunctions = { throw new Error('Unable to copy obj! Its type isn\'t supported.'); }, - + /** * This method validates an email address. If the address is not on the proper * form then the result is FALSE. - * + * * @param {string} email The email address to be checked. * @returns {bool} Returns the validation result. */ @@ -195,71 +195,71 @@ var GeneralFunctions = { var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; return reg.test(email); }, - + /** * This method returns the exception html display for javascript ajax calls. * It uses the Bootstrap collapse module to show exception messages when the * user opens the "Details" collapse component. - * + * * @param {array} exceptions Contains the exceptions to be displayed. * @returns {string} Returns the html markup for the exceptions. */ exceptionsToHtml: function(exceptions) { - var html = - '
' + - '
' + + var html = + '
' + + '
' + ''; - + $.each(exceptions, function(index, exception) { html += '
' + - '
' + + '
' + '
' + exception['message'] + '
' + '
' + '
'; }); - + html += '
'; - + return html; }, - + /** * This method parse the json encoded strings that are fetched by ajax calls. - * + * * @param {array} exceptions Exception array returned by an ajax call. * @returns {array} Returns the parsed js objects. */ parseExceptions: function(exceptions) { var parsedExceptions = new Array(); - + $.each(exceptions, function(index, exception) { parsedExceptions.push($.parseJSON(exception)); }); - + return parsedExceptions; }, - + /** * Makes the first letter of the string upper case. - * + * * @param {string} str The string to be converted. * @returns {string} Returns the capitalized string. */ ucaseFirstLetter: function(str){ return str.charAt(0).toUpperCase() + str.slice(1); }, - + /** * All backend js code has the same way of dislaying exceptions that are raised on the - * server during an ajax call. - * - * @param {object} response Contains the server response. If exceptions or warnings are + * server during an ajax call. + * + * @param {object} response Contains the server response. If exceptions or warnings are * found, user friendly messages are going to be displayed to the user. * @returns {bool} Returns whether the the ajax callback should continue the execution or * stop, due to critical server exceptions. @@ -277,26 +277,26 @@ var GeneralFunctions = { GeneralFunctions.displayMessageBox(GeneralFunctions.WARNINGS_TITLE, GeneralFunctions.WARNINGS_MESSAGE); $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings)); } - + return true; }, - + /** * Enables the language selection functionality. Must be called on every page has a * language selection button. This method requires the global variable 'availableLanguages' * to be initialized before the execution. - * + * * @param {object} $element Selected element button for the language selection. */ enableLanguageSelection: function($element) { // Select Language var html = '
    '; $.each(availableLanguages, function() { - html += '
  • ' + html += '
  • ' + GeneralFunctions.ucaseFirstLetter(this) + '
  • '; }); html += '
'; - + $element.popover({ 'placement': 'top', 'title': 'Select Language', @@ -305,7 +305,7 @@ var GeneralFunctions = { 'container': 'body', 'trigger': 'manual' }); - + $element.click(function() { if ($('#language-list').length == 0) { $(this).popover('show'); @@ -313,11 +313,11 @@ var GeneralFunctions = { $(this).popover('hide'); } }); - + $(document).on('click', 'li.language', function() { // Change language with ajax call and refresh page. var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_change_language'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, 'language': $(this).attr('data-language'), }; @@ -325,11 +325,11 @@ var GeneralFunctions = { //////////////////////////////////////////////////// console.log('Change Language Response', response); //////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; document.location.reload(true); - + }, 'json'); }); } -}; \ No newline at end of file +}; diff --git a/src/assets/js/installation.js b/src/assets/js/installation.js index fd399a2f..497caaf3 100644 --- a/src/assets/js/installation.js +++ b/src/assets/js/installation.js @@ -57,10 +57,18 @@ $(document).ready(function() { } }, error: function(jqXHR, textStatus, errorThrown) { - GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, - GeneralFunctions.EXCEPTIONS_MESSAGE); - console.log('The installation could be completed due to AJAX issues: ', - jqXHR, textStatus, errorThrown); + // Treat the error the same way as php exceptions. + var exc = { + exceptions: [ + JSON.stringify({ + message: 'The installation could not be completed due to an ' + + 'unexpected issue. Please check the browser\'s console for ' + + 'more information.' + }) + ] + }; + GeneralFunctions.handleAjaxExceptions(exc); + console.log(exc.exceptions[0].message, jqXHR, textStatus, errorThrown); } }); }); diff --git a/src/assets/js/working_plan.js b/src/assets/js/working_plan.js index 69b17174..3a2f15e3 100644 --- a/src/assets/js/working_plan.js +++ b/src/assets/js/working_plan.js @@ -1,41 +1,41 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * Contains the working plan functionality. The working plan DOM elements must be same + * Contains the working plan functionality. The working plan DOM elements must be same * in every page this class is used. - * + * * @class WorkingPlan */ var WorkingPlan = function() { /** * This flag is used when trying to cancel row editing. It is * true only whenever the user presses the cancel button. - * + * * @type {bool} */ this.enableCancel = false; - + /** - * This flag determines whether the jeditables are allowed to submit. It is + * This flag determines whether the jeditables are allowed to submit. It is * true only whenever the user presses the save button. - * + * * @type {bool} */ this.enableSubmit = false; }; /** - * Setup the dom elements of a given working plan. - * + * Setup the dom elements of a given working plan. + * * @param {object} workingPlan Contains the working hours and breaks for each day of the week. */ WorkingPlan.prototype.setup = function(workingPlan) { @@ -48,23 +48,23 @@ WorkingPlan.prototype.setup = function(workingPlan) { // Add the day's breaks on the breaks table. $.each(workingDay.breaks, function(i, brk) { var day = WorkingPlan.prototype.convertValueToDay(index); - - var tr = - '' + + + var tr = + '' + '' + GeneralFunctions.ucaseFirstLetter(day) + '' + '' + brk.start + '' + '' + brk.end + '' + - '' + - '' + - '' + - '' + - '' + '' + @@ -77,15 +77,15 @@ WorkingPlan.prototype.setup = function(workingPlan) { $('#' + index + '-end').prop('disabled', true); } }); - + // Make break cells editable. WorkingPlan.prototype.editableBreakDay($('.breaks .break-day')); WorkingPlan.prototype.editableBreakTime($('.breaks').find('.break-start, .break-end')); }; /** - * This method makes editable the break day cells. - * + * This method makes editable the break day cells. + * * @param {object} $selector The jquery selector ready for use. */ WorkingPlan.prototype.editableBreakDay = function($selector) { @@ -103,9 +103,6 @@ WorkingPlan.prototype.editableBreakDay = function($selector) { }, { 'type': 'select', 'data': weekDays, - // 'data': '{ "Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", ' - // + '"Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", ' - // + '"Sunday": "Sunday", "selected": "Monday"}', 'event': 'edit', 'height': '30px', 'submit': '', @@ -121,8 +118,8 @@ WorkingPlan.prototype.editableBreakDay = function($selector) { }; /** - * This method makes editable the break time cells. - * + * This method makes editable the break time cells. + * * @param {object} $selector The jquery selector ready for use. */ WorkingPlan.prototype.editableBreakTime = function($selector) { @@ -150,7 +147,7 @@ WorkingPlan.prototype.editableBreakTime = function($selector) { WorkingPlan.prototype.bindEventHandlers = function() { /** * Event: Day Checkbox "Click" - * + * * Enable or disable the time selection for each day. */ $('.working-plan input[type="checkbox"]').click(function() { @@ -167,27 +164,27 @@ WorkingPlan.prototype.bindEventHandlers = function() { /** * Event: Add Break Button "Click" - * - * A new row is added on the table and the user can enter the new break + * + * A new row is added on the table and the user can enter the new break * data. After that he can either press the save or cancel button. */ $('.add-break').click(function() { - var tr = - '' + + var tr = + '' + '' + EALang['monday'] + '' + '09:00' + '10:00' + - '' + - '' + - '' + - '' + - '' + '' + @@ -204,7 +201,7 @@ WorkingPlan.prototype.bindEventHandlers = function() { /** * Event: Edit Break Button "Click" - * + * * Enables the row editing for the "Breaks" table rows. */ $(document).on('click', '.edit-break', function() { @@ -229,13 +226,13 @@ WorkingPlan.prototype.bindEventHandlers = function() { // Show save - cancel buttons. $(this).closest('table').find('.edit-break, .delete-break').addClass('hidden'); $(this).parent().find('.save-break, .cancel-break').removeClass('hidden'); - + $('.add-break').prop('disabled', true); }); /** * Event: Delete Break Button "Click" - * + * * Removes the current line from the "Breaks" table. */ $(document).on('click', '.delete-break', function() { @@ -244,7 +241,7 @@ WorkingPlan.prototype.bindEventHandlers = function() { /** * Event: Cancel Break Button "Click" - * + * * Bring the ".breaks" table back to its initial state. */ $(document).on('click', '.cancel-break', function() { @@ -259,11 +256,11 @@ WorkingPlan.prototype.bindEventHandlers = function() { /** * Event: Save Break Button "Click" - * + * * Save the editable values and restore the table to its initial state. */ $(document).on('click', '.save-break', function() { - // Break's start time must always be prior to break's end. + // Break's start time must always be prior to break's end. var start = Date.parse($(this).parent().parent().find('.break-start input').val()); var end = Date.parse($(this).parent().parent().find('.break-end input').val()); if (start > end) { @@ -282,7 +279,7 @@ WorkingPlan.prototype.bindEventHandlers = function() { /** * Get the working plan settings. - * + * * @returns {object} Returns the working plan settings object. */ WorkingPlan.prototype.get = function() { @@ -294,53 +291,53 @@ WorkingPlan.prototype.get = function() { workingPlan[id].start = $('#' + id + '-start').val(); workingPlan[id].end = $('#' + id + '-end').val(); workingPlan[id].breaks = []; - + $('.breaks tr').each(function(index, tr) { var day = WorkingPlan.prototype.convertDayToValue( $(tr).find('.break-day').text()); if (day == id) { var start = $(tr).find('.break-start').text(); var end = $(tr).find('.break-end').text(); - + workingPlan[id].breaks.push({ 'start': start, 'end': end }); } }); - + } else { workingPlan[id] = null; } }); - + return workingPlan; }; /** - * Enables or disabled the timepicker functionality from the working plan input + * Enables or disabled the timepicker functionality from the working plan input * text fields. - * + * * @param {bool} disabled (OPTIONAL = false) If true then the timepickers will be * disabled. */ WorkingPlan.prototype.timepickers = function(disabled) { if (disabled == undefined) disabled == false; - + if (disabled == false) { // Set timepickers where needed. $('.working-plan input[type="text"]').timepicker({ 'timeFormat': 'HH:mm', - + currentText: EALang['now'], closeText: EALang['close'], timeOnlyTitle: EALang['select_time'], timeText: EALang['time'], hourText: EALang['hour'], minuteText: EALang['minutes'], - + 'onSelect': function(datetime, inst) { - // Start time must be earlier than end time. + // Start time must be earlier than end time. var start = Date.parse($(this).parent().parent().find('.work-start').val()); var end = Date.parse($(this).parent().parent().find('.work-end').val()); @@ -358,35 +355,35 @@ WorkingPlan.prototype.timepickers = function(disabled) { * Reset the current plan back to the company's default working plan. */ WorkingPlan.prototype.reset = function() { - + }; /** * This is necessary for translated days. - * + * * @param {string} value Day value could be like "monday", "tuesday" etc. */ WorkingPlan.prototype.convertValueToDay = function(value) { switch (value) { - case 'monday': + case 'monday': return EALang['monday']; break; - case 'tuesday': + case 'tuesday': return EALang['tuesday']; break; - case 'wednesday': + case 'wednesday': return EALang['wednesday']; break; - case 'thursday': + case 'thursday': return EALang['thursday']; break; - case 'friday': + case 'friday': return EALang['friday']; break; - case 'saturday': + case 'saturday': return EALang['saturday']; break; - case 'sunday': + case 'sunday': return EALang['sunday']; break; } @@ -394,31 +391,31 @@ WorkingPlan.prototype.convertValueToDay = function(value) { /** * This is necessary for translated days. - * + * * @param {string} value Day value could be like "Monday", "Tuesday" etc. */ WorkingPlan.prototype.convertDayToValue = function(day) { switch (day) { - case EALang['monday']: + case EALang['monday']: return 'monday'; break; - case EALang['tuesday']: + case EALang['tuesday']: return 'tuesday'; break; - case EALang['wednesday']: + case EALang['wednesday']: return 'wednesday'; break; - case EALang['thursday']: + case EALang['thursday']: return 'thursday'; break; - case EALang['friday']: + case EALang['friday']: return 'friday'; break; - case EALang['saturday']: + case EALang['saturday']: return 'saturday'; break; - case EALang['sunday']: + case EALang['sunday']: return 'sunday'; break; } -}; \ No newline at end of file +};