* Finished with backend/settings page.
* Started user login and privileges management.
This commit is contained in:
parent
4278e3d334
commit
fcc142a11b
15 changed files with 563 additions and 73 deletions
|
@ -58,5 +58,17 @@ define('AJAX_FAILURE', 'FAILURE');
|
|||
|
||||
define('SETTINGS_SYSTEM', 'SETTINGS_SYSTEM');
|
||||
define('SETTINGS_USER', 'SETTINGS_USER');
|
||||
|
||||
define('PRIV_VIEW', 1);
|
||||
define('PRIV_ADD', 2);
|
||||
define('PRIV_EDIT', 4);
|
||||
define('PRIV_DELETE', 8);
|
||||
|
||||
define('PAGE_APPOINTMENTS', 'appointments');
|
||||
define('PAGE_CUSTOMERS', 'customers');
|
||||
define('PAGE_SERVICES', 'services');
|
||||
define('PAGE_USERS', 'users');
|
||||
define('PAGE_SYSTEM_SETTINGS', 'system_settings');
|
||||
define('PAGE_USER_SETTINGS', 'user_settings');
|
||||
/* End of file constants.php */
|
||||
/* Location: ./application/config/constants.php */
|
|
@ -1,6 +1,11 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Backend extends CI_Controller {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->load->library('session');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the main backend page.
|
||||
*
|
||||
|
@ -13,7 +18,8 @@ class Backend extends CI_Controller {
|
|||
* appear when the page loads.
|
||||
*/
|
||||
public function index($appointment_hash = '') {
|
||||
// @task Require user to be logged in the application.
|
||||
$this->session->set_userdata('dest_url', $this->config->item('base_url') . 'backend');
|
||||
if (!$this->hasPrivileges(PAGE_APPOINTMENTS)) return;
|
||||
|
||||
$this->load->model('appointments_model');
|
||||
$this->load->model('providers_model');
|
||||
|
@ -47,7 +53,8 @@ class Backend extends CI_Controller {
|
|||
* In this page the user can manage all the customer records of the system.
|
||||
*/
|
||||
public function customers() {
|
||||
// @task Require user to be logged in the application.
|
||||
$this->session->set_userdata('dest_url', $this->config->item('base_url') . 'backend/customers');
|
||||
if (!$this->hasPrivileges(PAGE_CUSTOMERS)) return;
|
||||
|
||||
$this->load->model('providers_model');
|
||||
$this->load->model('customers_model');
|
||||
|
@ -75,7 +82,8 @@ class Backend extends CI_Controller {
|
|||
* from the backend services page.
|
||||
*/
|
||||
public function services() {
|
||||
// @task Require user to be logged in the application.
|
||||
$this->session->set_userdata('dest_url', $this->config->item('base_url') . 'backend/services');
|
||||
if (!$this->hasPrivileges(PAGE_SERVICES)) return;
|
||||
|
||||
$this->load->model('customers_model');
|
||||
$this->load->model('services_model');
|
||||
|
@ -99,7 +107,8 @@ class Backend extends CI_Controller {
|
|||
* the page where the admin defines which service can each provider provide.
|
||||
*/
|
||||
public function users() {
|
||||
// @task Require user to be logged in the application.
|
||||
$this->session->set_userdata('dest_url', $this->config->item('base_url') . 'backend/users');
|
||||
if (!$this->hasPrivileges(PAGE_USERS)) return;
|
||||
|
||||
$this->load->model('providers_model');
|
||||
$this->load->model('secretaries_model');
|
||||
|
@ -127,6 +136,10 @@ class Backend extends CI_Controller {
|
|||
* installation (core settings like company name, book timeout etc).
|
||||
*/
|
||||
public function settings() {
|
||||
$this->session->set_userdata('dest_url', $this->config->item('base_url') . 'backend/settings');
|
||||
if (!$this->hasPrivileges(PAGE_SYSTEM_SETTINGS)
|
||||
&& !$this->hasPrivileges(PAGE_USER_SETTINGS)) return;
|
||||
|
||||
$this->load->model('settings_model');
|
||||
$this->load->model('user_model');
|
||||
|
||||
|
@ -148,6 +161,48 @@ class Backend extends CI_Controller {
|
|||
$this->load->view('backend/settings', $view);
|
||||
$this->load->view('backend/footer', $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether current user is logged in and has the required privileges to
|
||||
* view a page.
|
||||
*
|
||||
* The backend page requires different privileges from the users to display pages. Not all
|
||||
* pages are avaiable to all users. For example secretaries should not be able to edit the
|
||||
* system users.
|
||||
*
|
||||
* @see Constant Definition In application/config/constants.php
|
||||
*
|
||||
* @param string $page This argument must match the roles field names of each section
|
||||
* (eg "appointments", "users" ...).
|
||||
* @param bool $redirect (OPTIONAL - TRUE) If the user has not the required privileges
|
||||
* (either not logged in or insufficient role privileges) then the user will be redirected
|
||||
* to another page. Set this argument to FALSE when using ajax.
|
||||
* @return bool Returns whether the user has the required privileges to view the page or
|
||||
* not. If the user is not logged in then he will be prompted to log in. If he hasn't the
|
||||
* required privileges then an info message will be displayed.
|
||||
*/
|
||||
private function hasPrivileges($page, $redirect = TRUE) {
|
||||
// Check if user is logged in.
|
||||
$user_id = $this->session->userdata('user_id');
|
||||
if ($user_id == FALSE) { // User not logged in, display the login view.
|
||||
if ($redirect) {
|
||||
header('Location: ' . $this->config->item('base_url') . 'user/login');
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check if the user has the required privileges for viewing the selected page.
|
||||
$role_slug = $this->session->userdata('role_slug');
|
||||
$role_priv = $this->db->get_where('ea_roles', array('slug' => $role_slug))->row_array();
|
||||
if ($role_priv[$page] < PRIV_VIEW) { // User does not have the permission to view the page.
|
||||
if ($redirect) {
|
||||
header('Location: ' . $this->config->item('base_url') . 'user/no_privileges');
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file backend.php */
|
||||
|
|
|
@ -811,10 +811,8 @@ class Backend_api extends CI_Controller {
|
|||
$settings = json_decode($_POST['settings'], true);
|
||||
$this->settings_model->save_settings($settings);
|
||||
} else if ($_POST['type'] == SETTINGS_USER) {
|
||||
$this->load->library('session');
|
||||
$this->load->model('user_model');
|
||||
$user_id = $this->session->userdata('user_id');
|
||||
$this->user_model->save_settings($_POST['settings'], $user_id);
|
||||
$this->user_model->save_settings(json_decode($_POST['settings'], true));
|
||||
}
|
||||
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
|
|
62
src/application/controllers/user.php
Normal file
62
src/application/controllers/user.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class User extends CI_Controller {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->load->library('session');
|
||||
}
|
||||
|
||||
public function index() {
|
||||
header('Location: ' . $this->config->item('base_url') . 'user/login');
|
||||
}
|
||||
|
||||
public function login() {
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
$view['dest_url'] = $this->session->userdata('dest_url');
|
||||
$this->load->view('user/login', $view);
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
|
||||
}
|
||||
|
||||
public function forgot_password() {
|
||||
|
||||
}
|
||||
|
||||
public function no_privileges() {
|
||||
// can't view the requested page.
|
||||
}
|
||||
|
||||
/**
|
||||
* [AJAX] Check whether the user has entered the correct login credentials.
|
||||
*/
|
||||
public function ajax_check_login() {
|
||||
try {
|
||||
if (!isset($_POST['username']) || !isset($_POST['password'])) {
|
||||
throw new Exception('Invalid credentials given!');
|
||||
}
|
||||
|
||||
$this->load->helper('general');
|
||||
$this->load->model('user_model');
|
||||
|
||||
$hash_password = $this->hash_password($_POST['password']);
|
||||
$user_data = $this->user_model->check_login($_POST['username'], $hash_password);
|
||||
|
||||
if ($user_data) {
|
||||
$this->session->set_userdata($user_data); // Save data on user's session.
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} else {
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
}
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file user.php */
|
||||
/* Location: ./application/controllers/user.php */
|
|
@ -25,5 +25,18 @@ function date3339($timestamp=0) {
|
|||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash of password string.
|
||||
*
|
||||
* For user security, all system passwords are stored in hash string into the database. Use
|
||||
* this method to produce the hash.
|
||||
*
|
||||
* @param string $password Given string password.
|
||||
* @return string Returns the hash string of the given password.
|
||||
*/
|
||||
function hash_password($password) {
|
||||
return md5($password); // @task include salt and hash more times.
|
||||
}
|
||||
|
||||
/* End of file general_helper.php */
|
||||
/* Location: ./application/helpers/general_helper.php */
|
|
@ -18,22 +18,32 @@ class User_Model extends CI_Model {
|
|||
* @return array Returns an array with user settings.
|
||||
*/
|
||||
public function get_settings($user_id) {
|
||||
$settings = $this->db->get_where('ea_user_settings', array('id_users' => $user_id))->row_array();
|
||||
unset($settings['id_users']);
|
||||
return $settings;
|
||||
$user = $this->db->get_where('ea_users', array('id' => $user_id))->row_array();
|
||||
$user['settings'] = $this->db->get_where('ea_user_settings', array('id_users' => $user_id))->row_array();
|
||||
unset($user['settings']['id_users']);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method saves the user settings into the database.
|
||||
*
|
||||
* @param array $settings Contains the current users settings.
|
||||
* @param numeric $user_id User record id of the settings.
|
||||
* @param array $user Contains the current users settings.
|
||||
* @return bool Returns the operation result.
|
||||
*/
|
||||
public function save_settings($settings, $user_id) {
|
||||
$settings['id_users'] = $user_id;
|
||||
$this->db->where('id_users', $user_id);
|
||||
return $this->db->update('ea_user_settings', $settings);
|
||||
public function save_settings($user) {
|
||||
$user_settings = $user['settings'];
|
||||
$user_settings['id_users'] = $user['id'];
|
||||
unset($user['settings']);
|
||||
|
||||
if (!$this->db->update('ea_users', $user, array('id' => $user['id']))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!$this->db->update('ea_user_settings', $user_settings, array('id_users' => $user['id']))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
record.</strong> After that you can add break periods.
|
||||
</span>
|
||||
|
||||
<table class="working-hours table table-striped">
|
||||
<table class="working-plan table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Day</th>
|
||||
|
@ -102,38 +102,38 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="monday" />Monday</label></td>
|
||||
<td><input type="text" id="monday-start" /></td>
|
||||
<td><input type="text" id="monday-end" /></td>
|
||||
<td><input type="text" id="monday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="monday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="tuesday" />Tuesday</label></td>
|
||||
<td><input type="text" id="tuesday-start" /></td>
|
||||
<td><input type="text" id="tuesday-end" /></td>
|
||||
<td><input type="text" id="tuesday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="tuesday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="wednesday" />Wednesday</label></td>
|
||||
<td><input type="text" id="wednesday-start" /></td>
|
||||
<td><input type="text" id="wednesday-end" /></td>
|
||||
<td><input type="text" id="wednesday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="wednesday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="thursday" />Thursday</label></td>
|
||||
<td><input type="text" id="thursday-start" /></td>
|
||||
<td><input type="text" id="thursday-end" /></td>
|
||||
<td><input type="text" id="thursday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="thursday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="friday" />Friday</label></td>
|
||||
<td><input type="text" id="friday-start" /></td>
|
||||
<td><input type="text" id="friday-end" /></td>
|
||||
<td><input type="text" id="friday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="friday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="saturday" />Saturday</label></td>
|
||||
<td><input type="text" id="saturday-start" /></td>
|
||||
<td><input type="text" id="saturday-end" /></td>
|
||||
<td><input type="text" id="saturday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="saturday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label class="checkbox"><input type="checkbox" id="sunday" />Sunday</label></td>
|
||||
<td><input type="text" id="sunday-start" /></td>
|
||||
<td><input type="text" id="sunday-end" /></td>
|
||||
<td><input type="text" id="sunday-start" class="work-start" /></td>
|
||||
<td><input type="text" id="sunday-end" class="work-end" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -206,16 +206,16 @@
|
|||
<input type="text" id="first-name" class="span9" />
|
||||
|
||||
<label for="last-name">Last Name *</label>
|
||||
<input type="text" id="last-name" class="span9" />
|
||||
<input type="text" id="last-name" class="span9 required" />
|
||||
|
||||
<label for="email">Email *</label>
|
||||
<input type="text" id="email" class="span9" />
|
||||
<input type="text" id="email" class="span9 required" />
|
||||
|
||||
<label for="mobile-number">Mobile Number</label>
|
||||
<input type="text" id="mobile-number" class="span9" />
|
||||
|
||||
<label for="phone-number">Phone Number</label>
|
||||
<input type="text" id="phone-number" class="span9" />
|
||||
<label for="phone-number">Phone Number *</label>
|
||||
<input type="text" id="phone-number" class="span9 required" />
|
||||
|
||||
<label for="address">Address</label>
|
||||
<input type="text" id="address" class="span9" />
|
||||
|
@ -237,17 +237,17 @@
|
|||
<legend>Miscellaneous</legend>
|
||||
|
||||
<label for="username">Username *</label>
|
||||
<input type="text" id="username" />
|
||||
<input type="text" id="username" class="required" />
|
||||
|
||||
<label for="password">Password *</label>
|
||||
<input type="text" id="password" />
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" />
|
||||
|
||||
<label for="retype-password">Retype Password *</label>
|
||||
<input type="text" id="retype-password" />
|
||||
<label for="retype-password">Retype Password</label>
|
||||
<input type="password" id="retype-password" />
|
||||
|
||||
<br>
|
||||
|
||||
<button type="button" class="btn" data-toggle="button">
|
||||
<button type="button" id="user-notifications" class="btn" data-toggle="button">
|
||||
<i class="icon-asterisk"></i>
|
||||
Receive Email Notifications
|
||||
</button>
|
||||
|
|
7
src/application/views/user/forgot_password.php
Normal file
7
src/application/views/user/forgot_password.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
?>
|
121
src/application/views/user/login.php
Normal file
121
src/application/views/user/login.php
Normal file
|
@ -0,0 +1,121 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
|
||||
<?php // INCLUDE JS FILES ?>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/bootstrap/bootstrap.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/date.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/general_functions.js"></script>
|
||||
|
||||
<?php // INCLUDE CSS FILES ?>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/css/libs/bootstrap/bootstrap.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/css/libs/bootstrap/bootstrap-responsive.css">
|
||||
|
||||
<?php // SET FAVICON FOR PAGE ?>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/images/favicon.ico">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #CAEDF3;
|
||||
}
|
||||
|
||||
#login-frame {
|
||||
width: 630px;
|
||||
margin: 150px auto 0 auto;
|
||||
background: #FFF;
|
||||
border: 1px solid #DDDADA;
|
||||
padding: 70px;
|
||||
}
|
||||
|
||||
#login-icon {
|
||||
float: right;
|
||||
margin-top: 17px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var GlobalVariables = {
|
||||
'baseUrl': <?php echo '"' . $base_url . '"'; ?>,
|
||||
'destUrl': <?php echo '"' . $dest_url . '"'; ?>
|
||||
};
|
||||
|
||||
/**
|
||||
* Event: Login Button "Click"
|
||||
*
|
||||
* Make an ajax call to the server and check whether the user's credentials are right.
|
||||
* If yes then redirect him to his desired page, otherwise display a message.
|
||||
*/
|
||||
$('#login').click(function() {
|
||||
var postUrl = GlobalVariables.baseUrl . 'user/ajax_check_login';
|
||||
var postData = {
|
||||
'username': $('#username').val(),
|
||||
'password': $('#password').val()
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
//////////////////////////////////////////////////
|
||||
console.log('Check Login Response: ', response);
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
if (response == true) {
|
||||
location(GlobalVariables.destUrl);
|
||||
} else {
|
||||
$('.alert').text('Login failed, please enter the correct credentials '
|
||||
+ 'and try again.');
|
||||
$('.alert').removeClass('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="login-frame" class="frame-container">
|
||||
<h2>Login Required</h2>
|
||||
<p>Welcome! You will need to login in order to view this page.</p>
|
||||
<hr>
|
||||
<div class="alert hidden"></div>
|
||||
<form>
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" placeholder="Enter your username here ..." />
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" placeholder="Enter your password here ..." />
|
||||
|
||||
<br><br>
|
||||
|
||||
<button type="button" id="login" class="btn btn-primary btn-large">Login</button>
|
||||
|
||||
<a href="<?php echo $base_url; ?>user/forgot_password" class="forgot-password">Forgot Your Password?</a>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
7
src/application/views/user/logout.php
Normal file
7
src/application/views/user/logout.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
?>
|
7
src/application/views/user/no_privileges.php
Normal file
7
src/application/views/user/no_privileges.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
?>
|
|
@ -384,12 +384,12 @@ body .modal-header h3 {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#business-logic .working-hours td input[type="text"] {
|
||||
#business-logic .working-plan td input[type="text"] {
|
||||
margin-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#business-logic .working-hours label.checkbox {
|
||||
#business-logic .working-plan label.checkbox {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -36,23 +36,21 @@ var Backend = {
|
|||
|
||||
/**
|
||||
* Place the backend footer always on the bottom of the page.
|
||||
*
|
||||
* @task Re-enable this method.
|
||||
*/
|
||||
placeFooterToBottom: function() {
|
||||
// var $footer = $('#footer');
|
||||
//
|
||||
// if (window.innerHeight > $('body').height()) {
|
||||
// $footer.css({
|
||||
// 'position': 'absolute',
|
||||
// 'width': '100%',
|
||||
// 'bottom': '0px'
|
||||
// });
|
||||
// } else {
|
||||
// $footer.css({
|
||||
// 'position': 'static'
|
||||
// });
|
||||
// }
|
||||
var $footer = $('#footer');
|
||||
|
||||
if (window.innerHeight > $('body').height()) {
|
||||
$footer.css({
|
||||
'position': 'absolute',
|
||||
'width': '100%',
|
||||
'bottom': '0px'
|
||||
});
|
||||
} else {
|
||||
$footer.css({
|
||||
'position': 'static'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,7 +42,7 @@ var BackendSettings = {
|
|||
initialize: function(bindEventHandlers) {
|
||||
if (bindEventHandlers == undefined) bindEventHandlers = true;
|
||||
|
||||
// Apply values from database.
|
||||
// Apply setting values from database.
|
||||
$.each(GlobalVariables.settings.system, function(index, setting) {
|
||||
$('input[data-field="' + setting.name + '"]').val(setting.value);
|
||||
});
|
||||
|
@ -93,19 +93,50 @@ var BackendSettings = {
|
|||
});
|
||||
|
||||
// Make break cells editable.
|
||||
BackendSettings.breakDayEditable($('#breaks .break-day'));
|
||||
BackendSettings.breakTimeEditable($('#breaks').find('.break-start, .break-end'));
|
||||
BackendSettings.editableBreakDay($('#breaks .break-day'));
|
||||
BackendSettings.editableBreakTime($('#breaks').find('.break-start, .break-end'));
|
||||
|
||||
// Set timepickers where needed.
|
||||
$('.working-hours input').timepicker({
|
||||
timeFormat: 'HH:mm'
|
||||
$('.working-plan input').timepicker({
|
||||
'timeFormat': 'HH:mm',
|
||||
'onSelect': function(datetime, inst) {
|
||||
// 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());
|
||||
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Book Advance Timeout Spinner
|
||||
$('#book-advance-timeout').spinner({
|
||||
min: 0
|
||||
'min': 0
|
||||
});
|
||||
|
||||
// Load user settings into form
|
||||
$('#user-id').val(GlobalVariables.settings.user.id);
|
||||
$('#first-name').val(GlobalVariables.settings.user.first_name);
|
||||
$('#last-name').val(GlobalVariables.settings.user.last_name);
|
||||
$('#email').val(GlobalVariables.settings.user.email);
|
||||
$('#mobile-number').val(GlobalVariables.settings.user.mobile_number);
|
||||
$('#phone-number').val(GlobalVariables.settings.user.phone_number);
|
||||
$('#address').val(GlobalVariables.settings.user.address);
|
||||
$('#city').val(GlobalVariables.settings.user.city);
|
||||
$('#state').val(GlobalVariables.settings.user.state);
|
||||
$('#zip-code').val(GlobalVariables.settings.user.zip_code);
|
||||
$('#notes').val(GlobalVariables.settings.user.notes);
|
||||
|
||||
$('#username').val(GlobalVariables.settings.user.settings.username);
|
||||
$('#password, #retype-password').val('');
|
||||
|
||||
if (GlobalVariables.settings.user.settings.notifications == true) {
|
||||
$('#user-notifications').addClass('active');
|
||||
} else {
|
||||
$('#user-notifications').removeClass('active');
|
||||
}
|
||||
|
||||
// Set default settings helper.
|
||||
BackendSettings.settings = new SystemSettings();
|
||||
|
||||
|
@ -114,6 +145,10 @@ var BackendSettings = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind the backend/settings default event handlers. This method depends on the
|
||||
* backend/settings html, so do not use this method on a different page.
|
||||
*/
|
||||
bindEventHandlers: function() {
|
||||
/**
|
||||
* Event: Tab "Click"
|
||||
|
@ -121,6 +156,11 @@ var BackendSettings = {
|
|||
* Change the visible tab contents.
|
||||
*/
|
||||
$('.tab').click(function() {
|
||||
// Bootstrap has a bug with toggle buttons. Their toggle state is lost when the
|
||||
// button is hidden or shown. Show before anything else we need to store the toggle
|
||||
// and apply it whenever the user tab is clicked..
|
||||
var areNotificationsActive = $('#user-notifications').hasClass('active');
|
||||
|
||||
$('.active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab-content').hide();
|
||||
|
@ -134,6 +174,13 @@ var BackendSettings = {
|
|||
} else if ($(this).hasClass('user-tab')) {
|
||||
$('#user').show();
|
||||
BackendSettings.settings = new UserSettings();
|
||||
|
||||
// Apply toggle state to user notifications button.
|
||||
if (areNotificationsActive) {
|
||||
$('#user-notifications').addClass('active');
|
||||
} else {
|
||||
$('#user-notifications').removeClass('active');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -145,6 +192,9 @@ var BackendSettings = {
|
|||
$('.save-settings').click(function() {
|
||||
var settings = BackendSettings.settings.get();
|
||||
BackendSettings.settings.save(settings);
|
||||
//////////////////////////////////////////////
|
||||
console.log('Settings To Save: ', settings);
|
||||
//////////////////////////////////////////////
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -152,7 +202,7 @@ var BackendSettings = {
|
|||
*
|
||||
* Enable or disable the time selection for each day.
|
||||
*/
|
||||
$('.working-hours input[type="checkbox"]').click(function() {
|
||||
$('.working-plan input[type="checkbox"]').click(function() {
|
||||
var id = $(this).attr('id');
|
||||
|
||||
if ($(this).prop('checked') == true) {
|
||||
|
@ -195,8 +245,8 @@ var BackendSettings = {
|
|||
|
||||
// Bind editable and event handlers.
|
||||
tr = $('#breaks tr').get()[1];
|
||||
BackendSettings.breakDayEditable($(tr).find('.break-day'));
|
||||
BackendSettings.breakTimeEditable($(tr).find('.break-start, .break-end'));
|
||||
BackendSettings.editableBreakDay($(tr).find('.break-day'));
|
||||
BackendSettings.editableBreakTime($(tr).find('.break-start, .break-end'));
|
||||
$(tr).find('.edit-break').trigger('click');
|
||||
});
|
||||
|
||||
|
@ -252,6 +302,13 @@ var BackendSettings = {
|
|||
* 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.
|
||||
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) {
|
||||
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
|
||||
BackendSettings.enableSubmit = true;
|
||||
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
|
||||
BackendSettings.enableSubmit = false;
|
||||
|
@ -266,7 +323,7 @@ var BackendSettings = {
|
|||
*
|
||||
* @param {object} $selector The cells to be initialized.
|
||||
*/
|
||||
breakDayEditable: function($selector) {
|
||||
editableBreakDay: function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
return value;
|
||||
}, {
|
||||
|
@ -293,7 +350,7 @@ var BackendSettings = {
|
|||
*
|
||||
* @param {object} $selector The cells to be initialized.
|
||||
*/
|
||||
breakTimeEditable: function($selector) {
|
||||
editableBreakTime: function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
// Do not return the value because the user needs to press the "Save" button.
|
||||
return value;
|
||||
|
@ -362,13 +419,27 @@ SystemSettings.prototype.get = function() {
|
|||
|
||||
// Business Logic Tab
|
||||
var workingPlan = {};
|
||||
$('.working-hours input[type="checkbox"').each(function() {
|
||||
$('.working-plan input[type="checkbox"').each(function() {
|
||||
var id = $(this).attr('id');
|
||||
if ($(this).prop('checked') == true) {
|
||||
workingPlan[id] = {}
|
||||
workingPlan[id].start = $('#' + id + '-start').val();
|
||||
workingPlan[id].end = $('#' + id + '-end').val();
|
||||
workingPlan[id].breaks = {};
|
||||
workingPlan[id].breaks = [];
|
||||
|
||||
$('#breaks tr').each(function(index, tr) {
|
||||
var day = $(tr).find('.break-day').text().toLowerCase();
|
||||
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;
|
||||
|
@ -380,6 +451,11 @@ SystemSettings.prototype.get = function() {
|
|||
'value': JSON.stringify(workingPlan)
|
||||
});
|
||||
|
||||
settings.push({
|
||||
'name': 'book_advance_timeout',
|
||||
'value': $('#book-advance-timeout').val()
|
||||
});
|
||||
|
||||
return settings;
|
||||
};
|
||||
|
||||
|
@ -390,7 +466,32 @@ SystemSettings.prototype.get = function() {
|
|||
* @returns {bool} Returns the validation result.
|
||||
*/
|
||||
SystemSettings.prototype.validate = function() {
|
||||
$('#general .required').css('border', '');
|
||||
|
||||
try {
|
||||
// Validate required fields.
|
||||
var missingRequired = false;
|
||||
$('#general .required').each(function() {
|
||||
if ($(this).val() == '' || $(this).val() == undefined) {
|
||||
$(this).css('border', '2px solid red');
|
||||
missingRequired = true;
|
||||
}
|
||||
});
|
||||
if (missingRequired) {
|
||||
throw 'Fields with * are required.';
|
||||
}
|
||||
|
||||
// Validate company email address.
|
||||
if (!GeneralFunctions.validateEmail($('#company-email').val())) {
|
||||
$('#company-email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
Backend.displayNotification(exc);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -402,10 +503,33 @@ var UserSettings = function() {};
|
|||
/**
|
||||
* Get the settings data for the user settings.
|
||||
*
|
||||
* @returns {array} Returns the user settings array.
|
||||
* @returns {object} Returns the user settings array.
|
||||
*/
|
||||
UserSettings.prototype.get = function() {
|
||||
var user = {
|
||||
'id': $('#user-id').val(),
|
||||
'first_name': $('#first-name').val(),
|
||||
'last_name': $('#last-name').val(),
|
||||
'email': $('#email').val(),
|
||||
'mobile_number': $('#mobile-number').val(),
|
||||
'phone_number': $('#phone-number').val(),
|
||||
'address': $('#address').val(),
|
||||
'city': $('#city').val(),
|
||||
'state': $('#state').val(),
|
||||
'zip_code': $('#zip-code').val(),
|
||||
'notes': $('#notes').val(),
|
||||
'settings': {
|
||||
'username': $('#username').val(),
|
||||
'password': $('#password').val(),
|
||||
'notifications': $('#user-notifications').hasClass('active')
|
||||
}
|
||||
};
|
||||
|
||||
if ($('#password').val() != '') {
|
||||
user.settings.password = $('#password').val();
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -414,7 +538,27 @@ UserSettings.prototype.get = function() {
|
|||
* @param {array} settings Contains the user settings.
|
||||
*/
|
||||
UserSettings.prototype.save = function(settings) {
|
||||
if (!BackendSettings.settings.validate(settings)) {
|
||||
Backend.displayNotification('User settings are invalid! Please review your settings '
|
||||
+ 'and try again.');
|
||||
return; // Validation failed, do not procceed.
|
||||
}
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_settings';
|
||||
var postData = {
|
||||
'type': BackendSettings.SETTINGS_USER,
|
||||
'settings': JSON.stringify(settings)
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
//////////////////////////////////////////////////////////
|
||||
console.log('Save User Settings Response: ', response);
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
if (!Backend.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Settings saved successfully!');
|
||||
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -424,5 +568,37 @@ UserSettings.prototype.save = function(settings) {
|
|||
* @returns {bool} Returns the validation result.
|
||||
*/
|
||||
UserSettings.prototype.validate = function() {
|
||||
$('#user .required').css('border', '');
|
||||
$('#user').find('#password, #retype-password').css('border', '');
|
||||
|
||||
try {
|
||||
// Validate required fields.
|
||||
var missingRequired = false;
|
||||
$('#user .required').each(function() {
|
||||
if ($(this).val() == '' || $(this).val() == undefined) {
|
||||
$(this).css('border', '2px solid red');
|
||||
missingRequired = true;
|
||||
}
|
||||
});
|
||||
if (missingRequired) {
|
||||
throw 'Fields with * are required.';
|
||||
}
|
||||
|
||||
// Validate passwords (if provided).
|
||||
if ($('#password').val() != $('#retype-password').val()) {
|
||||
$('#password, #retype-password').css('border', '2px solid red');
|
||||
throw 'Passwords mismatch!';
|
||||
}
|
||||
|
||||
// Validate user email.
|
||||
if (!GeneralFunctions.validateEmail($('#email').val())) {
|
||||
$('#email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
Backend.displayNotification(exc);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -589,6 +589,12 @@ AdminsHelper.prototype.validate = function(admin) {
|
|||
throw 'Passwords mismatch!';
|
||||
}
|
||||
|
||||
// Validate user email.
|
||||
if (!GeneralFunctions.validateEmail($('#admin-email').val())) {
|
||||
$('#admin-email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
$('#admins .form-message').text(exc);
|
||||
|
@ -611,6 +617,8 @@ AdminsHelper.prototype.resetForm = function() {
|
|||
$('#admins .form-message').hide();
|
||||
$('#admin-notifications').removeClass('active');
|
||||
$('#admin-notifications').prop('disabled', true);
|
||||
$('#admins .required').css('border', '');
|
||||
$('#admin-password, #admin-password-confirm').css('border', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -764,6 +772,12 @@ ProvidersHelper.prototype.validate = function(provider) {
|
|||
throw 'Passwords mismatch!';
|
||||
}
|
||||
|
||||
// Validate user email.
|
||||
if (!GeneralFunctions.validateEmail($('#provider-email').val())) {
|
||||
$('#provider-email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
$('#providers .form-message').text(exc);
|
||||
|
@ -788,6 +802,8 @@ ProvidersHelper.prototype.resetForm = function() {
|
|||
$('#provider-notifications').prop('disabled', true);
|
||||
$('#provider-services input[type="checkbox"]').prop('checked', false);
|
||||
$('#provider-services input[type="checkbox"]').prop('disabled', true);
|
||||
$('#providers .required').css('border', '');
|
||||
$('#provider-password, #provider-password-confirm').css('border', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -950,6 +966,12 @@ SecretariesHelper.prototype.validate = function(secretary) {
|
|||
throw 'Passwords mismatch!';
|
||||
}
|
||||
|
||||
// Validate user email.
|
||||
if (!GeneralFunctions.validateEmail($('#secretary-email').val())) {
|
||||
$('#secretary-email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
$('#secretaries .form-message').text(exc);
|
||||
|
@ -974,6 +996,8 @@ SecretariesHelper.prototype.resetForm = function() {
|
|||
$('#secretary-notifications').prop('disabled', true);
|
||||
$('#secretary-providers input[type="checkbox"]').prop('checked', false);
|
||||
$('#secretary-providers input[type="checkbox"]').prop('disabled', true);
|
||||
$('#secretaries .required').css('border', '');
|
||||
$('#secretary-password, #secretary-password-confirm').css('border', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue