* Added "Forgot Password" procedure.
* Started working on the installation page. * Fixed minor bugs in backend pages.
This commit is contained in:
parent
538c34ecd4
commit
a5ef8fb491
25 changed files with 780 additions and 35 deletions
BIN
rsc/design/logo/installation-banner.png
Normal file
BIN
rsc/design/logo/installation-banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
rsc/design/logo/installation-banner.psd
Normal file
BIN
rsc/design/logo/installation-banner.psd
Normal file
Binary file not shown.
|
@ -12,6 +12,8 @@ class Appointments extends CI_Controller {
|
|||
* record.
|
||||
*/
|
||||
public function index($appointment_hash = '') {
|
||||
if (!$this->check_installation()) return;
|
||||
|
||||
$this->load->model('appointments_model');
|
||||
$this->load->model('providers_model');
|
||||
$this->load->model('services_model');
|
||||
|
@ -602,6 +604,41 @@ class Appointments extends CI_Controller {
|
|||
|
||||
return $available_periods_with_appointments;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks whether the application is installed.
|
||||
*
|
||||
* This method resides in this controller because the "index()" function will
|
||||
* be the first to be launched after the files are on the server. NOTE that the
|
||||
* "configuration.php" file must be already set because we won't be able to
|
||||
* connect to the database otherwise.
|
||||
*/
|
||||
public function check_installation() {
|
||||
try {
|
||||
if (!$this->db->table_exists('ea_users')) {
|
||||
// This is the first time the website is launched an the user needs to set
|
||||
// the basic settings.
|
||||
|
||||
// We will use mysqli to create the database structure from the "structure.sql" file.
|
||||
require_once dirname(dirname(dirname(__FILE__))) . '/configuration.php';
|
||||
$mysqli = new mysqli(SystemConfiguration::$db_host, SystemConfiguration::$db_username,
|
||||
SystemConfiguration::$db_password, SystemConfiguration::$db_name);
|
||||
$structure = file_get_contents($this->config->item('base_url') . 'assets/sql/structure.sql');
|
||||
$mysqli->multi_query($structure);
|
||||
$mysqli->close();
|
||||
|
||||
// Display the installation view page.
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
$this->load->view('general/installation', $view);
|
||||
|
||||
return FALSE; // Do not display the book appointment view file.
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
echo $exc->getTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file appointments.php */
|
||||
|
|
|
@ -174,7 +174,7 @@ class Backend extends CI_Controller {
|
|||
$user_id = $this->session->userdata('user_id');
|
||||
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
$view['user_display_name'] = $this->user_model->get_user_display_name($this->session->userdata('user_id'));
|
||||
$view['user_display_name'] = $this->user_model->get_user_display_name($user_id);
|
||||
$view['active_menu'] = PRIV_SYSTEM_SETTINGS;
|
||||
$view['company_name'] = $this->settings_model->get_setting('company_name');
|
||||
$view['role_slug'] = $this->session->userdata('role_slug');
|
||||
|
|
|
@ -29,12 +29,12 @@ class User extends CI_Controller {
|
|||
$this->session->unset_userdata('dest_url');
|
||||
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
|
||||
$this->load->view('user/logout', $view);
|
||||
}
|
||||
|
||||
public function forgot_password() {
|
||||
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
$this->load->view('user/forgot_password', $view);
|
||||
}
|
||||
|
||||
public function no_privileges() {
|
||||
|
@ -73,6 +73,43 @@ class User extends CI_Controller {
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate a new password for the current user, only if the username and
|
||||
* email address given corresond to an existing user in db.
|
||||
*
|
||||
* @param string $_POST['username']
|
||||
* @param string $_POST['email']
|
||||
*/
|
||||
public function ajax_forgot_password() {
|
||||
try {
|
||||
if (!isset($_POST['username']) || !isset($_POST['email'])) {
|
||||
throw new Exception('You must enter a valid username and email address in '
|
||||
. 'order to get a new password!');
|
||||
}
|
||||
|
||||
$this->load->model('user_model');
|
||||
$this->load->model('settings_model');
|
||||
|
||||
$new_password = $this->user_model->regenerate_password($_POST['username'], $_POST['email']);
|
||||
|
||||
if ($new_password != FALSE) {
|
||||
$this->load->library('notifications');
|
||||
$company_settings = array(
|
||||
'company_name' => $this->settings_model->get_setting('company_name'),
|
||||
'company_link' => $this->settings_model->get_setting('company_link'),
|
||||
'company_email' => $this->settings_model->get_setting('company_email')
|
||||
);
|
||||
$this->notifications->send_password($new_password, $_POST['email'], $company_settings);
|
||||
}
|
||||
|
||||
echo ($new_password != FALSE) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file user.php */
|
||||
|
|
|
@ -61,5 +61,21 @@ function generate_salt() {
|
|||
return substr($salt, 0, $max_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates a random string.
|
||||
*
|
||||
* @param int $length (OPTIONAL = 10) The length of the generated string.
|
||||
* @return string Returns the randomly generated string.
|
||||
* @link http://stackoverflow.com/a/4356295/1718162
|
||||
*/
|
||||
function generate_random_string($length = 10) {
|
||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$random_string = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$random_string .= $characters[rand(0, strlen($characters) - 1)];
|
||||
}
|
||||
return $random_string;
|
||||
}
|
||||
|
||||
/* End of file general_helper.php */
|
||||
/* Location: ./application/helpers/general_helper.php */
|
|
@ -164,6 +164,45 @@ class Notifications {
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sends an email with the new password of a user.
|
||||
*
|
||||
* @param string $password Contains the new password.
|
||||
* @param string $email The receiver's email address.
|
||||
*/
|
||||
public function send_password($password, $email, $company_settings) {
|
||||
$replace_array = array(
|
||||
'$email_title' => 'New Account Password',
|
||||
'$email_message' => 'Your new account password is <strong>' . $password . '</strong>. '
|
||||
. 'Please store this email to be able to retrieve your password if necessary. '
|
||||
. 'You can also change this password with a new one in the settings page.',
|
||||
'$company_name' => $company_settings['company_name'],
|
||||
'$company_email' => $company_settings['company_email'],
|
||||
'$company_link' => $company_settings['company_link']
|
||||
);
|
||||
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__))
|
||||
. '/views/emails/new_password.php');
|
||||
$email_html = $this->replace_template_variables($replace_array, $email_html);
|
||||
|
||||
// :: SETUP EMAIL OBJECT AND SEND NOTIFICATION
|
||||
$mail = new PHPMailer();
|
||||
$mail->From = $company_settings['company_email'];
|
||||
$mail->FromName = $company_settings['company_name'];
|
||||
$mail->AddAddress($email); // "Name" argument crushes the phpmailer class.
|
||||
$mail->IsHTML(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Subject = 'New Account Password';
|
||||
$mail->Body = $email_html;
|
||||
|
||||
if (!$mail->Send()) {
|
||||
throw new Exception('Email could not been sent. '
|
||||
. 'Mailer Error (Line ' . __LINE__ . '): ' . $mail->ErrorInfo);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file notifications.php */
|
||||
|
|
|
@ -102,6 +102,38 @@ class User_Model extends CI_Model {
|
|||
$user = $this->db->get_where('ea_users', array('id' => $user_id))->row_array();
|
||||
return $user['first_name'] . ' ' . $user['last_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given arguments correspond to an existing user record, generate a new
|
||||
* password and send it with an email.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $email
|
||||
* @return string|bool Returns the new password on success or FALSE on failure.
|
||||
*/
|
||||
public function regenerate_password($username, $email) {
|
||||
$this->load->helper('general');
|
||||
|
||||
$result = $this->db
|
||||
->select('ea_users.id')
|
||||
->from('ea_users')
|
||||
->join('ea_user_settings', 'ea_user_settings.id_users = ea_users.id', 'inner')
|
||||
->where('ea_users.email', $email)
|
||||
->where('ea_user_settings.username', $username)
|
||||
->get();
|
||||
|
||||
if ($result->num_rows() == 0) return FALSE;
|
||||
|
||||
$user_id = $result->row()->id;
|
||||
|
||||
// Create a new password and send it with an email to the given email address.
|
||||
$new_password = generate_random_string();
|
||||
$salt = $this->db->get_where('ea_user_settings', array('id_users' => $user_id))->row()->salt;
|
||||
$hash_password = hash_password($salt, $new_password);
|
||||
$this->db->update('ea_user_settings', array('password' => $hash_password), array('id_users' => $user_id));
|
||||
|
||||
return $new_password;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file user_model.php */
|
||||
|
|
|
@ -346,7 +346,7 @@
|
|||
// ------------------------------------------------------ ?>
|
||||
<div id="frame-footer">
|
||||
Powered By
|
||||
<a href="https://code.google.com/p/easy-appointments/">
|
||||
<a href="http://easyappointments.org" target="_blank">
|
||||
Easy!Appointments
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
|
||||
<div id="calendar-actions">
|
||||
<div class="btn-group">
|
||||
<?php if ($privileges[PRIV_USERS]['edit'] == TRUE) { ?>
|
||||
<?php //if ($privileges[PRIV_USERS]['edit'] == TRUE) { ?>
|
||||
<?php if ($role_slug == DB_SLUG_ADMIN || $role_slug == DB_SLUG_PROVIDER) { ?>
|
||||
<button id="google-sync" class="btn btn-primary"
|
||||
title="Trigger the Google Calendar synchronization process.">
|
||||
<i class="icon-refresh icon-white"></i>
|
||||
|
|
|
@ -62,27 +62,27 @@
|
|||
</legend>
|
||||
|
||||
<label for="company-name">Company Name *</label>
|
||||
<input type="text" id="company-name" data-field="company_name">
|
||||
<input type="text" id="company-name" data-field="company_name" class="required">
|
||||
<span class="help-block">Company name will be displayed everywhere on the system
|
||||
(required).</span>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="company-email">Company Email *</label>
|
||||
<input type="text" id="company-email" data-field="company_email">
|
||||
<input type="text" id="company-email" data-field="company_email" class="required">
|
||||
<span class="help-block">This will be the company email address. It will be used
|
||||
as the sender and the reply address of the system emails (required).</span>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="company-link">Company Link</label>
|
||||
<input type="text" id="company-link" data-field="company_link">
|
||||
<label for="company-link">Company Link *</label>
|
||||
<input type="text" id="company-link" data-field="company_link" class="required">
|
||||
<span class="help-block">Company link should point to the official website of
|
||||
the company (optional).</span>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="<?php echo $this->config->base_url(); ?>" target="blank" class="btn btn-primary">
|
||||
<a href="<?php echo $this->config->base_url(); ?>" target="_blank" class="btn btn-primary">
|
||||
<i class="icon-calendar icon-white"></i>
|
||||
Go To Booking Page
|
||||
</a>
|
||||
|
|
24
src/application/views/emails/new_password.php
Normal file
24
src/application/views/emails/new_password.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>New Account Password</title>
|
||||
</head>
|
||||
<body style="font: 13px arial, helvetica, tahoma;">
|
||||
<div class="email-container" style="width: 650px;border: 1px solid #eee;">
|
||||
<div id="header" style="background-color: #3DD481; border-bottom: 4px solid #1A865F;
|
||||
height: 40px;padding: 10px 15px;">
|
||||
<strong id="logo" style="color: white; font-size: 31px;
|
||||
text-shadow: 1px 1px 1px #8F8888;">$company_name</strong>
|
||||
</div>
|
||||
|
||||
<div id="content" style="padding: 10px 15px;">
|
||||
<h2>$email_title</h2>
|
||||
<p>$email_message</p>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
border-top: 1px solid #EEE;background: #FAFAFA;">
|
||||
<a href="$company_link">$company_name</a> | Powered by Easy!Appointments
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
215
src/application/views/general/installation.php
Normal file
215
src/application/views/general/installation.php
Normal file
|
@ -0,0 +1,215 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<?php // PAGE META ?>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Easy!Appointments - Installation</title>
|
||||
|
||||
<?php // INCLUDE CSS ?>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $base_url; ?>assets/css/libs/bootstrap/bootstrap.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $base_url; ?>assets/css/libs/bootstrap/bootstrap-responsive.css">
|
||||
|
||||
<?php // SET FAVICON FOR PAGE ?>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="<?php echo $base_url(); ?>assets/images/favicon.ico">
|
||||
|
||||
<?php // INCLUDE SCRIPTS ?>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/libs/bootstrap/bootstrap.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/libs/date.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/general_functions.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var GlobalVariables = {
|
||||
'baseUrl': <?php echo '"' . $base_url . '"'; ?>
|
||||
};
|
||||
|
||||
/**
|
||||
* Event: Install System "Click"
|
||||
*/
|
||||
$('#install').click(function() {
|
||||
if (!validate()) return;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'ajax_install';
|
||||
var postData = {
|
||||
'admin': getAdminData(),
|
||||
'company': getCompanyDate()
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Validates the user input. Use this before executing the installation procedure.
|
||||
*
|
||||
* @returns {bool} Returns the validation result.
|
||||
*/
|
||||
function validate() {
|
||||
try {
|
||||
$('.alert').fadeOut();
|
||||
$('input[type="text"]').css('border', '');
|
||||
|
||||
// Check for empty fields.
|
||||
var missingRequired = false;
|
||||
$('input[type="text"]').each(function() {
|
||||
if ($(this).val() == '') {
|
||||
$(this).css('border', '2px solid red');
|
||||
missingRequired = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (missingRequired)
|
||||
throw 'All the page fields are required.';
|
||||
|
||||
// Validate Passwords
|
||||
if ($('#password').val() != $('#retype-password').val()) {
|
||||
$('#password').css('border', '2px solid red');
|
||||
$('#retype-password').css('border', '2px solid red');
|
||||
throw 'Passwords do not match!';
|
||||
}
|
||||
|
||||
// Validate Email
|
||||
if (!GeneralFunctions.validateEmail($('#email').val())) {
|
||||
$('#email').css('border', '2px solid red');
|
||||
throw 'The email addres is invalid!';
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
$('.alert').txt(exc);
|
||||
$('.alert').fadeIn();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the admin data as an object.
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
function getAdminData() {
|
||||
var admin = {
|
||||
'first_name': $('#first-name').val(),
|
||||
'last_name': $('#last-name').val(),
|
||||
'email': $('#email').val(),
|
||||
'phone_number': $('#phone-number').val(),
|
||||
'username': $('#username').val(),
|
||||
'password': $('#password').val()
|
||||
};
|
||||
|
||||
return admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the company data as an object.
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
function getCompanyData() {
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="http://easyappointments.org" target="_blank">
|
||||
<img src="<?php echo $base_url; ?>assets/images/installation-banner.png" alt="Easy!Appointents Installation Banner">
|
||||
</a>
|
||||
</header>
|
||||
<div class="content">
|
||||
<div class="welcome">
|
||||
<h2>Welcome To The Easy!Appointments Installation Page</h2>
|
||||
<p>
|
||||
This page will help you set the main settings of your Easy!Appointments installation.
|
||||
You will be able to edit these settings and many more in the backend session of your
|
||||
system. Remember to use the <span class="label label-info"><?php echo $base_url; ?>
|
||||
backend</span> url to connect to the backend section of Easy!Appointments.
|
||||
|
||||
If you face any problems during the usage of Easy!Appointments you can always check
|
||||
the official <a href="https://code.google.com/p/easy-appointments/w/list">Wiki Pages</a>
|
||||
and the <a href="http://groups.google.com/group/easy-appointments">Support Group</a>
|
||||
for getting help. You may also submit new issues on the
|
||||
<a href="https://code.google.com/p/easy-appointments/issues/list">Google Code Issues</a>
|
||||
page, in order to help our development process.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="alert" style="display: none"></div>
|
||||
|
||||
<div class="admin-settings">
|
||||
<h2>Administrator Settings</h2>
|
||||
<label for="first-name">First Name</label>
|
||||
<input type="text" id="first-name" />
|
||||
|
||||
<label for="last-name">Last Name</label>
|
||||
<input type="text" id="last-name" />
|
||||
|
||||
<label for="email">Email</label>
|
||||
<input type="text" id="email" />
|
||||
|
||||
<label for="phone-number">Phone Number</label>
|
||||
<input type="text" id="phone-number" />
|
||||
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" />
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" />
|
||||
|
||||
<label for="retype-password">Retype Password</label>
|
||||
<input type="password" id="retype-password" />
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="company-settings">
|
||||
<h2>Company Settings</h2>
|
||||
<label for="company-name">Company Name</label>
|
||||
<input type="text" id="company-name">
|
||||
|
||||
<label for="company-email">Company Email</label>
|
||||
<input type="text" id="company-email">
|
||||
|
||||
<label for="company-link">Company Link</label>
|
||||
<input type="text" id="company-link">
|
||||
|
||||
<div class="alert alert-info">
|
||||
You will be able to set your business logic in the backend settings page after
|
||||
the installation is complete.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<center>
|
||||
<button type="button" id="install" class="btn btn-success btn-large">
|
||||
<i class="icon-white icon-ok"></i>
|
||||
Install</button>
|
||||
</center>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
Powered by <a href="http://easyappointments.org">Easy!Appointments</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,124 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
?>
|
||||
<!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;
|
||||
}
|
||||
|
||||
#forgot-password-frame {
|
||||
width: 630px;
|
||||
margin: 150px auto 0 auto;
|
||||
background: #FFF;
|
||||
border: 1px solid #DDDADA;
|
||||
padding: 70px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.user-login{
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var GlobalVariables = {
|
||||
'baseUrl': <?php echo '"' . $base_url . '"'; ?>,
|
||||
'AJAX_SUCCESS': 'SUCCESS',
|
||||
'AJAX_FAILURE': 'FAILURE'
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
$('form').submit(function() {
|
||||
event.preventDefault();
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'user/ajax_forgot_password';
|
||||
var postData = {
|
||||
'username': $('#username').val(),
|
||||
'email': $('#email').val()
|
||||
};
|
||||
|
||||
$('.alert').addClass('hidden');
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
//////////////////////////////////////////////////////////
|
||||
console.log('Regenerate Password Response: ', response);
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
if (response == GlobalVariables.AJAX_SUCCESS) {
|
||||
$('.alert').addClass('alert-success');
|
||||
$('.alert').text('Your new password has been sent to you with an email.');
|
||||
} else {
|
||||
$('.alert').text('The operation failed! Please enter a valid username '
|
||||
+ 'and email address in order to get a new password.');
|
||||
}
|
||||
$('.alert').removeClass('hidden');
|
||||
}, 'json');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="forgot-password-frame" class="frame-container">
|
||||
<h2>Forgot Your Password?</h2>
|
||||
<p>Type your username and your email address to get your new password.</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="email">Email</label>
|
||||
<input type="text" id="email" placeholder="Enter your email here ..." />
|
||||
|
||||
<br><br>
|
||||
|
||||
<button type="submit" id="get-new-password" class="btn btn-primary btn-large">Regenerate Password</button>
|
||||
|
||||
<a href="<?php echo $base_url; ?>user/login" class="user-login">Go Back To Login Page</a>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -70,7 +70,7 @@
|
|||
</a>
|
||||
|
||||
<a href="<?php echo $this->config->base_url(); ?>backend" class="btn btn-danger btn-large">
|
||||
<i class="icon-wrench icon-white"></i>
|
||||
<i class="icon-home icon-white"></i>
|
||||
Backend Section
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -53,12 +53,13 @@ root {
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
#header #header-menu .menu-item:hover {
|
||||
#header #header-menu .menu-item:hover:not(.active) {
|
||||
background-color: #247A4B;
|
||||
}
|
||||
|
||||
#header #header-menu .active {
|
||||
color: #D6FF80;
|
||||
color: #E7FFB3;
|
||||
text-shadow: 1px 1px 0px #57814D;
|
||||
}
|
||||
|
||||
#footer {
|
||||
|
|
BIN
src/assets/images/installation-banner.png
Normal file
BIN
src/assets/images/installation-banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -342,7 +342,7 @@ CustomersHelper.prototype.display = function(customer) {
|
|||
'</div>';
|
||||
$('#customer-appointments').append(html);
|
||||
});
|
||||
$('#customer-appointments').jScrollPane();
|
||||
$('#customer-appointments').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -375,8 +375,7 @@ CustomersHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = BackendCustomers.helper.getFilterHtml(customer);
|
||||
$('#filter-customers .results').append(html);
|
||||
});
|
||||
|
||||
$('#filter-customers .results').jScrollPane();
|
||||
$('#filter-customers .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-customers .results').html('<em>No records found...</em>');
|
||||
|
|
|
@ -54,7 +54,7 @@ var BackendServices = {
|
|||
* Changes the displayed tab.
|
||||
*/
|
||||
$('.tab').click(function() {
|
||||
$('.active').removeClass('active');
|
||||
$(this).parent().find('.active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab-content').hide();
|
||||
|
||||
|
@ -389,7 +389,7 @@ ServicesHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = ServicesHelper.prototype.getFilterHtml(service);
|
||||
$('#filter-services .results').append(html);
|
||||
});
|
||||
$('#filter-services .results').jScrollPane();
|
||||
$('#filter-services .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-services .result').html('<em>No results found ...</em>');
|
||||
|
@ -613,7 +613,7 @@ CategoriesHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = BackendServices.helper.getFilterHtml(category);
|
||||
$('#filter-categories .results').append(html);
|
||||
});
|
||||
$('#filter-categories .results').jScrollPane();
|
||||
$('#filter-categories .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-categories .results').html('<em>No records found...</em>');
|
||||
|
|
|
@ -116,7 +116,7 @@ var BackendSettings = {
|
|||
// and apply it whenever the user tab is clicked..
|
||||
var areNotificationsActive = $('#user-notifications').hasClass('active');
|
||||
|
||||
$('.active').removeClass('active');
|
||||
$(this).parent().find('.active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab-content').hide();
|
||||
|
||||
|
|
|
@ -49,14 +49,14 @@ var BackendUsers = {
|
|||
+ service.name + '</label>';
|
||||
$('#provider-services').append(html);
|
||||
});
|
||||
$('#provider-services').jScrollPane();
|
||||
$('#provider-services').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
$.each(GlobalVariables.providers, function(index, provider) {
|
||||
var html = '<label class="checkbox"><input type="checkbox" data-id="' + provider.id + '" />'
|
||||
+ provider.first_name + ' ' + provider.last_name + '</label>';
|
||||
$('#secretary-providers').append(html);
|
||||
});
|
||||
$('#secretary-providers').jScrollPane();
|
||||
$('#secretary-providers').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
// Bind event handlers.
|
||||
if (defaultEventHandlers) BackendUsers.bindEventHandlers();
|
||||
|
@ -73,7 +73,7 @@ var BackendUsers = {
|
|||
* Changes the displayed tab.
|
||||
*/
|
||||
$('.tab').click(function() {
|
||||
$('.active').removeClass('active');
|
||||
$(this).parent().find('.active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab-content').hide();
|
||||
|
||||
|
@ -83,7 +83,7 @@ var BackendUsers = {
|
|||
} else if ($(this).hasClass('providers-tab')) { // display providers tab
|
||||
$('#providers').show();
|
||||
$('#provider-services').data('jsp').destroy();
|
||||
$('#provider-services').jScrollPane();
|
||||
$('#provider-services').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
BackendUsers.helper = new ProvidersHelper();
|
||||
} else if ($(this).hasClass('secretaries-tab')) { // display secretaries tab
|
||||
$('#secretaries').show();
|
||||
|
@ -109,7 +109,7 @@ var BackendUsers = {
|
|||
$('#secretary-providers').append(html);
|
||||
});
|
||||
$('#secretary-providers input[type="checkbox"]').prop('disabled', true);
|
||||
$('#secretary-providers').jScrollPane();
|
||||
$('#secretary-providers').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
}, 'json');
|
||||
}
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ AdminsHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = AdminsHelper.prototype.getFilterHtml(admin);
|
||||
$('#filter-admins .results').append(html);
|
||||
});
|
||||
$('#filter-admins .results').jScrollPane();
|
||||
$('#filter-admins .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-admins .results').html('<em>No results found ...</em>')
|
||||
|
|
|
@ -397,7 +397,7 @@ ProvidersHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = ProvidersHelper.prototype.getFilterHtml(provider);
|
||||
$('#filter-providers .results').append(html);
|
||||
});
|
||||
$('#filter-providers .results').jScrollPane();
|
||||
$('#filter-providers .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-providers .results').html('<em>No results found ...</em>')
|
||||
|
|
|
@ -351,7 +351,7 @@ SecretariesHelper.prototype.filter = function(key, selectId, display) {
|
|||
var html = SecretariesHelper.prototype.getFilterHtml(secretary);
|
||||
$('#filter-secretaries .results').append(html);
|
||||
});
|
||||
$('#filter-secretaries .results').jScrollPane();
|
||||
$('#filter-secretaries .results').jScrollPane({ mouseWheelSpeed: 70 });
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-secretaries .results').html('<em>No results found ...</em>')
|
||||
|
|
227
src/assets/sql/structure.sql
Normal file
227
src/assets/sql/structure.sql
Normal file
|
@ -0,0 +1,227 @@
|
|||
-- phpMyAdmin SQL Dump
|
||||
-- version 3.5.1
|
||||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Φιλοξενητής: localhost
|
||||
-- Χρόνος δημιουργίας: 11 Οκτ 2013 στις 16:58:08
|
||||
-- Έκδοση διακομιστή: 5.5.24-log
|
||||
-- Έκδοση PHP: 5.4.3
|
||||
|
||||
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
|
||||
--
|
||||
-- Βάση: `easy_appointments`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_appointments`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_appointments` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`book_datetime` datetime DEFAULT NULL,
|
||||
`start_datetime` datetime DEFAULT NULL,
|
||||
`end_datetime` datetime DEFAULT NULL,
|
||||
`notes` text,
|
||||
`hash` text,
|
||||
`is_unavailable` tinyint(4) DEFAULT '0',
|
||||
`id_users_provider` bigint(20) unsigned DEFAULT NULL,
|
||||
`id_users_customer` bigint(20) unsigned DEFAULT NULL,
|
||||
`id_services` bigint(20) unsigned DEFAULT NULL,
|
||||
`id_google_calendar` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_users_customer` (`id_users_customer`),
|
||||
KEY `id_services` (`id_services`),
|
||||
KEY `id_users_provider` (`id_users_provider`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=63 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_roles`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_roles` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(256) DEFAULT NULL,
|
||||
`slug` varchar(256) DEFAULT NULL,
|
||||
`is_admin` tinyint(4) DEFAULT NULL COMMENT '0',
|
||||
`appointments` int(4) DEFAULT NULL COMMENT '0',
|
||||
`customers` int(4) DEFAULT NULL COMMENT '0',
|
||||
`services` int(4) DEFAULT NULL COMMENT '0',
|
||||
`users` int(4) DEFAULT NULL COMMENT '0',
|
||||
`system_settings` int(4) DEFAULT NULL COMMENT '0',
|
||||
`user_settings` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_secretaries_providers`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` (
|
||||
`id_users_secretary` bigint(20) unsigned NOT NULL,
|
||||
`id_users_provider` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id_users_secretary`,`id_users_provider`),
|
||||
KEY `fk_ea_secretaries_providers_1` (`id_users_secretary`),
|
||||
KEY `fk_ea_secretaries_providers_2` (`id_users_provider`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_services`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_services` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(256) DEFAULT NULL,
|
||||
`duration` int(11) DEFAULT NULL,
|
||||
`price` decimal(10,2) DEFAULT NULL,
|
||||
`currency` varchar(32) DEFAULT NULL,
|
||||
`description` text,
|
||||
`id_service_categories` bigint(20) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_service_categories` (`id_service_categories`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_services_providers`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_services_providers` (
|
||||
`id_users` bigint(20) unsigned NOT NULL,
|
||||
`id_services` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id_users`,`id_services`),
|
||||
KEY `id_services` (`id_services`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_service_categories`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_service_categories` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(256) DEFAULT NULL,
|
||||
`description` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=24 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_settings`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_settings` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(512) DEFAULT NULL,
|
||||
`value` longtext,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_users`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_users` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`first_name` varchar(256) DEFAULT NULL,
|
||||
`last_name` varchar(512) DEFAULT NULL,
|
||||
`email` varchar(512) DEFAULT NULL,
|
||||
`mobile_number` varchar(128) DEFAULT NULL,
|
||||
`phone_number` varchar(128) DEFAULT NULL,
|
||||
`address` varchar(256) DEFAULT NULL,
|
||||
`city` varchar(256) DEFAULT NULL,
|
||||
`state` varchar(128) DEFAULT NULL,
|
||||
`zip_code` varchar(64) DEFAULT NULL,
|
||||
`notes` text,
|
||||
`id_roles` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_roles` (`id_roles`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=84 ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Δομή πίνακα για τον πίνακα `ea_user_settings`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_user_settings` (
|
||||
`id_users` bigint(20) unsigned NOT NULL,
|
||||
`username` varchar(256) DEFAULT NULL,
|
||||
`password` varchar(512) DEFAULT NULL,
|
||||
`salt` varchar(512) DEFAULT NULL,
|
||||
`working_plan` text,
|
||||
`notifications` tinyint(4) DEFAULT '0',
|
||||
`google_sync` tinyint(4) DEFAULT '0',
|
||||
`google_token` text,
|
||||
`sync_past_days` int(11) DEFAULT '5',
|
||||
`sync_future_days` int(11) DEFAULT '5',
|
||||
PRIMARY KEY (`id_users`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για άχρηστους πίνακες
|
||||
--
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_appointments`
|
||||
--
|
||||
ALTER TABLE `ea_appointments`
|
||||
ADD CONSTRAINT `ea_appointments_ibfk_2` FOREIGN KEY (`id_users_customer`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
ADD CONSTRAINT `ea_appointments_ibfk_3` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
ADD CONSTRAINT `ea_appointments_ibfk_4` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_secretaries_providers`
|
||||
--
|
||||
ALTER TABLE `ea_secretaries_providers`
|
||||
ADD CONSTRAINT `fk_ea_secretaries_providers_1` FOREIGN KEY (`id_users_secretary`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
ADD CONSTRAINT `fk_ea_secretaries_providers_2` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_services`
|
||||
--
|
||||
ALTER TABLE `ea_services`
|
||||
ADD CONSTRAINT `ea_services_ibfk_1` FOREIGN KEY (`id_service_categories`) REFERENCES `ea_service_categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_services_providers`
|
||||
--
|
||||
ALTER TABLE `ea_services_providers`
|
||||
ADD CONSTRAINT `ea_services_providers_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
ADD CONSTRAINT `ea_services_providers_ibfk_2` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_users`
|
||||
--
|
||||
ALTER TABLE `ea_users`
|
||||
ADD CONSTRAINT `ea_users_ibfk_1` FOREIGN KEY (`id_roles`) REFERENCES `ea_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Περιορισμοί για πίνακα `ea_user_settings`
|
||||
--
|
||||
ALTER TABLE `ea_user_settings`
|
||||
ADD CONSTRAINT `ea_user_settings_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
Loading…
Reference in a new issue