Υλοποίηση κύριας λειτουργίας των τεσσάρων βημάτων της κράτησης ραντεβού. Λείπουν επιπλέον λειτουργίες ελέχγου των δεδομένων και η μορφοποίηση της σελίδας.

This commit is contained in:
alextselegidis@gmail.com 2013-04-16 21:37:36 +00:00
parent b715bfa19d
commit 918903de62
22 changed files with 333 additions and 47 deletions

View file

@ -5,11 +5,45 @@ class Appointments extends CI_Controller {
* This page displays the book appointment wizard
* for the customers.
*/
public function index()
{
public function index() {
// Get business name.
$this->load->model('Settings');
$viewData['businessName'] = $this->Settings->getSetting('business_name');
// Get the available services and providers.
$this->load->model('Services');
$viewData['availableServices'] = $this->Services->getAvailableServices();
$this->load->model('Providers');
$viewData['availableProviders'] = $this->Providers->getAvailableProviders(); // Provider rows contain an array of which services they can provide.
// Load the book appointment view.
$this->load->view('appointments/book', $viewData);
}
/**
* This method answers to an AJAX request. It calculates the
* available hours for the given service, provider and date.
*
* @param array $_POST['postData'] An associative array that
* contains the user selected service, provider and date.
*/
public function getAvailableHours() {
/*** CHECK BUSINESS WORKING HOURS ***/
/*** CHECK PROVIDERS WORKING HOURS ***/
/*** CHECK ALREADY BOOKED APPOINTMENTS ***/
/*** RETURN AVAILABLE HOURS ***/
// ------------------------------------------------------------------
// For now we just need to return a sample array. Dynamic calculation
// will be adding in future development.
$startTime = strtotime($_POST['selectedDate'] . ' 08:00') / 60; // Convert to minutes
$endTime = strtotime($_POST['selectedDate'] . ' 16:00') / 60; // Convert to minutes
for ($i=0; ($startTime*60 + $i*60)<=($endTime*60); $i+=intval($_POST['serviceDuration'])) {
$availableHours[] = date('H:i', $startTime * 60 + $i * 60);
}
echo json_encode($availableHours);
}
}

View file

@ -1,7 +1,44 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
?>
class Providers extends CI_Model {
public function __construct() {
parent::__construct();
}
/**
* This method returns the available providers and
* the services that can provide.
*
* @return array Returns an array with the providers
* data.
*/
public function getAvailableProviders() {
$sql = '
SELECT ea_users.*
FROM ea_users
INNER JOIN ea_roles
ON ea_users.id_roles = ea_roles.id
WHERE ea_roles.slug = "provider"';
$providers = $this->db->query($sql)->result_array();
foreach($providers as &$provider) {
$sql = '
SELECT id_services
FROM ea_services_providers
WHERE id_users = ' . $this->db->escape($provider['id']);
$providerServices = $this->db->query($sql)->result_array();
if (!isset($provider['services'])) {
$provider['services'] = array();
}
foreach($providerServices as $providerService) {
$provider['services'][] = $providerService['id_services'];
}
}
return $providers;
}
}
?>

View file

@ -10,10 +10,8 @@ class Services extends CI_Model {
* @return array Returns an object array with all the
* database services.
*/
function getAllServices() {
$query = $this->db->query('SELECT *');
return $this->db->get('ea_services');
function getAvailableServices() {
return $this->db->get('ea_services')->result_array();
}
}
?>

View file

@ -27,7 +27,6 @@ class Settings extends CI_Model {
*
* @param string $name The setting name.
* @param type $value The setting value.
*
* @return bool Returns the operation success - failure
* result.
*/

View file

@ -1,6 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<?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">
@ -13,13 +15,151 @@
<script type="text/javascript" src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery-ui.min.js"></script>
<script type="text/javascript" src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.qtip.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>
<?php // SET FAVICON FOR PAGE ?>
<link rel="icon" type="image/x-icon" href="<?php echo $this->config->base_url(); ?>assets/images/favicon.ico">
<script type="text/javascript">
$(document).ready(function() {
var services = <?php echo json_encode($availableServices); ?>;
var providers = <?php echo json_encode($availableProviders); ?>;
// When the user clicks on a service, its available providers should
// become visible.
$('#select-service').change(function() {
var currServiceId = $('#select-service').val();
$('#select-provider').empty();
$.each(providers, function(index, provider) {
$.each(provider['services'], function(index, serviceId) {
if (serviceId == currServiceId) {
// This provider can provide the selected service.
// Add him to the list box.
var option = new Option(provider['last_name'] + ' ' + provider['first_name'], provider['id']);
$('#select-provider').append(option);
}
});
});
refreshAvailableHours(Date.today().toString('MM/dd/yyyy'));
});
/**
* Selected Provider Changed Event Handler
*/
$('#select-provider').change(function() {
refreshAvailableHours(Date.today().toString('MM/dd/yyyy'));
});
$('#select-service').trigger('change');
$('.book-step').qtip({
position: {
my: 'top center',
at: 'bottom center'
},
style: {
classes: 'qtip-green qtip-shadow custom-qtip'
}
});
$('#select-date').datepicker({
//dateFormat : 'dd/mm/yy',
onSelect : function(dateText, inst) {
refreshAvailableHours(dateText);
}
});
refreshAvailableHours(Date.today().toString('MM/dd/yyyy'));
/**
* Next Step Button Clicked
*/
$('.button-next').click(function() {
var nextTabIndex = parseInt($(this).attr('data-step_index')) + 1;
$(this).parents().eq(1).hide('fade', function() {
$('.active-step').removeClass('active-step');
$('#step-' + nextTabIndex).addClass('active-step');
$('#book-appointment-' + nextTabIndex).show('fade');
});
});
/**
* Back Step Button Clicked
*/
$('.button-back').click(function() {
var prevTabIndex = parseInt($(this).attr('data-step_index')) - 1;
$(this).parents().eq(1).hide('fade', function() {
$('.active-step').removeClass('active-step');
$('#step-' + prevTabIndex).addClass('active-step');
$('#book-appointment-' + prevTabIndex).show('fade');
});
});
/**
* Available Hour Click Event Handler
*/
$('#available-hours').on('click', '.available-hour', function() {
$('.selected-hour').removeClass('selected-hour');
$(this).addClass('selected-hour');
});
/**
* This function makes an ajax call and returns the available
* hours for the selected service, provider and date.
*/
function refreshAvailableHours(selDate) {
// Fetch the available hours of the current date
// for the chosen service and provider.
var selServiceDuration = 15; // Default duration.
$.each(services, function(index, service) {
if (service['id'] == $('#select-service').val()) {
selServiceDuration = service['duration'];
}
})
var postData = {
'serviceId' : $('#select-service').val(),
'providerId' : $('#select-provider').val(),
'selectedDate' : selDate,
'serviceDuration' : selServiceDuration
};
console.log('\n\n Get Available Hours Post Data:', postData, '\n\n');
// Make ajax post request and get the available hours.
var ajaxurl = '<?php echo $this->config->base_url(); ?>index.php/appointments/getAvailableHours';
jQuery.post(ajaxurl, postData, function(postResponse) {
////////////////////////////////////////////////////////////////////////////////
console.log('\n\n Get Available Hours Post Response :', postResponse, '\n\n');
////////////////////////////////////////////////////////////////////////////////
try {
var jsonResponse = jQuery.parseJSON(postResponse);
////////////////////////////////////////////////////////////////////////////////
console.log('\n\n Get Available Hours Json Response :', jsonResponse, '\n\n');
////////////////////////////////////////////////////////////////////////////////
// Fill the available time div
var currColumn = 1;
$('#available-hours').html('<div style="width:50px; float:left;"></div>');
$.each(jsonResponse, function(index, availableHour) {
if ((currColumn * 10) < (index + 1)) {
currColumn++;
$('#available-hours').append('<div style="width:50px; float:left;"></div>');
}
$('#available-hours div:eq(' + (currColumn - 1) + ')')
.append('<span class="available-hour">' + availableHour + '</span><br/>');
});
} catch(exception) {
// @task Display message to the user.
};
});
}
});
</script>
</head>
@ -51,35 +191,96 @@
<h2>Select Service & Provider</h2>
<label for="select-service">Select Service</label>
<select id="select-service">
<option value="1">General Examination</option>
<option value="2">Check Blood Pressure</option>
<?php
foreach($availableServices as $service) {
echo '<option value="' . $service['id'] . '">' . $service['name'] . '</option>';
}
?>
</select>
<label for="select-provider">Select Provider</label>
<select id="select-provider">
<option value="1">Dr. Andy Smith</option>
<option value="2">Dr. Peter Grol</option>
<option value="3">Dr. Kurt Benstein</option>
</select>
<select id="select-provider"></select>
<button type="button" id="button-next-1" class="btn">Next</button>
<div class="command-buttons">
<button type="button" id="button-next-1" class="btn button-next" data-step_index="1">Next</button>
</div>
</div>
<?php // APPOINTMENT DATE ?>
<div id="book-appointment-2" class="book-appoinment-step">
<div id="book-appointment-2" class="book-appoinment-step" style="display:none;">
<h2>Select Appointment Date And Time</h2>
<div class="span3">
<div id="select-date"></div>
</div>
<div class="span3">
<?php // Available hours are going to be fetched via ajax call. ?>
<div id="available-hours"></div>
</div>
<div class="command-buttons">
<button type="button" id="button-back-2" class="btn button-back" data-step_index="2">Back</button>
<button type="button" id="button-next-2" class="btn button-next" data-step_index="2">Next</button>
</div>
</div>
<?php // CUSTOMER'S INFO ?>
<div id="book-appointment-3" class="book-appoinment-step">
<div id="book-appointment-3" class="book-appoinment-step" style="display:none;">
<h2>Fill In Your Information</h2>
<div class="span3">
<label for="last-name">Last Name *</label>
<input type="text" id="last-name" maxlength="250" />
<label for="first-name">First Name</label>
<input type="text" id="first-name" maxlength="100" />
<label for="email">Email *</label>
<input type="text" id="email" maxlength="250" />
<label for="phone-number">Phone Number *</label>
<input type="text" id="phone-number" maxlength="60" />
</div>
<div class="span3">
<label for="address">Address</label>
<input type="text" id="address" maxlength="250" />
<label for="city">City</label>
<input type="text" id="city" maxlength="120" />
<label for="zip-code">Zip Code</label>
<input type="text" id="zip-code" maxlength="120" />
<label for="notes">Notes</label>
<textarea id="notes" maxlength="500"></textarea>
</div>
<div class="command-buttons">
<button type="button" id="button-back-3" class="btn button-back" data-step_index="3">Back</button>
<button type="button" id="button-next-3" class="btn button-next" data-step_index="3">Next</button>
</div>
</div>
<?php // CONFIRMATION STEP ?>
<div id="book-appointment-4" class="book-appoinment-step">
<div id="book-appointment-4" class="book-appoinment-step" style="display:none;">
<h2>Confirm Appointment</h2>
<div id="appointment-info">
</div>
<div id="customer-info">
</div>
<div class="command-buttons">
<button type="button" id="button-back-4" class="btn button-back" data-step_index="4">Back</button>
<form>
<button type="submit" class="btn-success">Confirm Appointment</button>
</form>
</div>
</div>
<div id="frame-footer">

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

File diff suppressed because one or more lines are too long

View file

@ -14,9 +14,10 @@ body {
------------------------------------------------------------------------------ */
#book-appointment {
width: 660px;
margin: 150px auto;
margin: 150px auto 0 auto;
background: #FFF;
box-shadow: 0px 1px 1px #B6B6B6;
min-height: 480px;
}
#book-appointment #top-bar {
@ -40,39 +41,34 @@ body {
width: 252px;
display: inline-block;
float: right;
margin-top: 12px;
margin-top: 15px;
}
#book-appointment .book-appoinment-step {
padding: 10px 20px;
height: 363px;
}
#book-appointment .book-step {
display: inline-block;
height: 28px;
width: 28px;
height: 20px;
width: 20px;
float: left;
background: #E1FFCF;
background: #FFF;
padding: 10px;
margin-right: 15px;
border-radius: 50px;
box-shadow: inset 1px 1px 3px #2B2B2B;
border: 3px solid #38A07A;
}
#book-appointment .book-step strong {
font-size: 29px;
font-size: 25px;
display: block;
text-align: center;
margin-top: 4px;
color: #B6DFC6;
}
#book-appointment .active-step {
background: #FAFA99;
}
#book-appointment .active-step strong {
color: #696439;
color: #396946;
}
#book-appointment #frame-footer {
@ -80,4 +76,20 @@ body {
text-align: center;
border-top: 1px solid #EEE;
background: #FAFAFA;
}
}
.custom-qtip {
border-width: 2px;
}
#available-hours .available-hour:hover {
font-weight: bold;
background-color: #CAEDF3;
cursor: pointer;
}
#available-hours .selected-hour {
color: #0088cc;
font-weight: bold;
text-decoration: underline;
}

File diff suppressed because one or more lines are too long