forked from mirrors/easyappointments
- Τροποποιήσεις στα αρχεία και την δομή του κώδικα
- Υλοποίηση της πρώτης σελίδας του backend της εφαρμογής.
This commit is contained in:
parent
fcf58a7cf2
commit
6369da0893
20 changed files with 1155 additions and 65 deletions
|
@ -102,16 +102,18 @@ class Appointments extends CI_Controller {
|
||||||
|
|
||||||
// Synchronize the appointment with the providers plan, if the
|
// Synchronize the appointment with the providers plan, if the
|
||||||
// google sync option is enabled.
|
// google sync option is enabled.
|
||||||
$this->load->library('google_sync');
|
|
||||||
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
||||||
$appointment_data['id_users_provider']);
|
$appointment_data['id_users_provider']);
|
||||||
|
|
||||||
if ($google_sync == TRUE) {
|
if ($google_sync == TRUE) {
|
||||||
$google_token = $this->Providers_Model->get_setting('google_token',
|
$google_token = $this->Providers_Model->get_setting('google_token',
|
||||||
$appointment_data['id_users_provider']);
|
$appointment_data['id_users_provider']);
|
||||||
// Validate the token. If it isn't valid, the sync operation cannot
|
|
||||||
|
// Authenticate the token. If it isn't valid, the sync operation cannot
|
||||||
// be completed.
|
// be completed.
|
||||||
if ($this->google_sync->validate_token($google_token) === TRUE) {
|
$this->load->library('google_sync');
|
||||||
|
|
||||||
|
if ($this->google_sync->authenticate($google_token) === TRUE) {
|
||||||
if ($manage_mode === FALSE) {
|
if ($manage_mode === FALSE) {
|
||||||
// Add appointment to Google Calendar.
|
// Add appointment to Google Calendar.
|
||||||
$this->google_sync->add_appointment($appointment_data['id']);
|
$this->google_sync->add_appointment($appointment_data['id']);
|
||||||
|
@ -122,7 +124,7 @@ class Appointments extends CI_Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the book appointment view.
|
// Load the book success view.
|
||||||
$service_data = $this->Services_Model->get_row($appointment_data['id_services']);
|
$service_data = $this->Services_Model->get_row($appointment_data['id_services']);
|
||||||
$provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']);
|
$provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']);
|
||||||
$company_name = $this->Settings_Model->get_setting('company_name');
|
$company_name = $this->Settings_Model->get_setting('company_name');
|
||||||
|
@ -180,10 +182,22 @@ class Appointments extends CI_Controller {
|
||||||
|
|
||||||
// Delete the appointment from Google Calendar, if it is synced.
|
// Delete the appointment from Google Calendar, if it is synced.
|
||||||
if ($appointment_data['id_google_calendar'] != NULL) {
|
if ($appointment_data['id_google_calendar'] != NULL) {
|
||||||
$this->load->library('google_sync');
|
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
||||||
$this->google_sync->delete_appointment($appointment_data['id']);
|
$appointment_data['id_users_provider']);
|
||||||
|
|
||||||
|
if ($google_sync == TRUE) {
|
||||||
|
$this->load->library('google_sync');
|
||||||
|
|
||||||
|
// Get the provider's refresh token and try to authenticate the
|
||||||
|
// Google Calendar API usage.
|
||||||
|
$google_token = $this->Providers_Model->get_setting('google_token',
|
||||||
|
$appointment_data['id_users_provider']);
|
||||||
|
|
||||||
|
if ($this->google_sync->authendicate($google_token) === TRUE) {
|
||||||
|
$this->google_sync->delete_appointment($appointment_data['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(Exception $exc) {
|
} catch(Exception $exc) {
|
||||||
// Display the error message to the customer.
|
// Display the error message to the customer.
|
||||||
$view_data['error_message'] = $exc->getMessage();
|
$view_data['error_message'] = $exc->getMessage();
|
||||||
|
|
48
src/application/controllers/backend.php
Normal file
48
src/application/controllers/backend.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||||
|
|
||||||
|
class Backend extends CI_Controller {
|
||||||
|
/**
|
||||||
|
* Display the main backend page.
|
||||||
|
*
|
||||||
|
* This method displays the main backend page. All users login permission can
|
||||||
|
* view this page which displays a calendar with the events of the selected
|
||||||
|
* provider or service. If a user has more priviledges he will see more menus
|
||||||
|
* at the top of the page.
|
||||||
|
*/
|
||||||
|
public function index() {
|
||||||
|
// @task Require user to be logged in the application.
|
||||||
|
|
||||||
|
$this->load->model('Providers_Model');
|
||||||
|
$this->load->model('Services_Model');
|
||||||
|
$this->load->model('Settings_Model');
|
||||||
|
|
||||||
|
// Display the main backend page.
|
||||||
|
$view_data['base_url'] = $this->config->item('base_url');
|
||||||
|
$view_data['company_name'] = $this->Settings_Model->get_setting('company_name');
|
||||||
|
$view_data['available_providers'] = $this->Providers_Model->get_available_providers();
|
||||||
|
$view_data['available_services'] = $this->Services_Model->get_available_services();
|
||||||
|
|
||||||
|
$this->load->view('backend/header', $view_data);
|
||||||
|
$this->load->view('backend/calendar', $view_data);
|
||||||
|
$this->load->view('backend/footer', $view_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function customers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function services() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function settings() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of file backend.php */
|
||||||
|
/* Location: ./application/controllers/backend.php */
|
|
@ -37,22 +37,21 @@ class Google_Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the Google API access token of a provider.
|
* Authenticate the Google API usage.
|
||||||
*
|
*
|
||||||
* In order to manage a Google user's data, one need a valid access token.
|
* This method must be executed every time we need to make actions on a
|
||||||
* This token is provided when the user grants the permission to a system
|
* provider's Google Calendar account. A new token is necessary and the
|
||||||
* to access his Google account data. So before making any action we need
|
* only way to get it is to use the stored refresh token that was provided
|
||||||
* to make sure that the available token is still valid.
|
* when the provider granted consent to Easy!Appointments for use his
|
||||||
|
* Google Calendar account.
|
||||||
*
|
*
|
||||||
* <strong>IMPORTANT!</strong> Always use this method before anything else
|
* @param string $refresh_token The provider's refresh token. This value is
|
||||||
* in order to make sure that the token is being set and still valid.
|
* stored in the database and used every time we need to make actions to his
|
||||||
*
|
* Google Caledar account.
|
||||||
* @param string $access_token This token is normally stored in the database.
|
* @return bool Returns the authenticate operation result.
|
||||||
* @return bool Returns the validation result.
|
|
||||||
*/
|
*/
|
||||||
public function validate_token($access_token) {
|
public function authenticate($refresh_token) {
|
||||||
$this->client->setAccessToken($access_token);
|
|
||||||
return $this->client->isAccessTokenExpired();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css"
|
type="text/css"
|
||||||
href="<?php echo $this->config->base_url(); ?>assets/css/style.css">
|
href="<?php echo $this->config->base_url(); ?>assets/css/frontend.css">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
@ -34,32 +34,25 @@
|
||||||
// ------------------------------------------------------------ ?>
|
// ------------------------------------------------------------ ?>
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery-ui.min.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery-ui.min.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.qtip.min.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.qtip.min.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/bootstrap/bootstrap.min.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/bootstrap/bootstrap.min.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/date.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/date.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/frontend/book_appointment.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/frontend_book.js"></script>
|
||||||
</script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/general_functions.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/general_functions.js"></script>
|
||||||
</script>
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
@ -86,7 +79,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
bookAppointment.initialize(true, GlobalVariables.manageMode);
|
FrontendBook.initialize(true, GlobalVariables.manageMode);
|
||||||
GeneralFunctions.centerElementOnPage($('#book-appointment-wizard'));
|
GeneralFunctions.centerElementOnPage($('#book-appointment-wizard'));
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -149,16 +149,16 @@
|
||||||
'Your appointment has successfully been added to ' +
|
'Your appointment has successfully been added to ' +
|
||||||
'your Google Calendar account. <br>' +
|
'your Google Calendar account. <br>' +
|
||||||
'<a href="' + response.htmlLink + '">' +
|
'<a href="' + response.htmlLink + '">' +
|
||||||
'Appointment Link' +
|
'Click here to view your appoinmtent on Google ' +
|
||||||
|
'Calendar.' +
|
||||||
'</a>' +
|
'</a>' +
|
||||||
'</p>' +
|
'</p>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
);
|
);
|
||||||
|
$('#add-to-google-calendar').hide();
|
||||||
} else {
|
} else {
|
||||||
throw 'Could not add the event to Google Calendar.';
|
throw 'Could not add the event to Google Calendar.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch(exc) {
|
} catch(exc) {
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
<?php // INCLUDE JS FILES ?>
|
<?php // INCLUDE JS FILES ?>
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js">
|
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js"></script>
|
||||||
</script>
|
|
||||||
|
|
||||||
<?php // INCLUDE CSS FILES ?>
|
<?php // INCLUDE CSS FILES ?>
|
||||||
<link
|
<link
|
||||||
|
|
46
src/application/views/backend/calendar.php
Normal file
46
src/application/views/backend/calendar.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="<?php echo $base_url; ?>assets/css/libs/jquery/fullcalendar.css" />
|
||||||
|
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="<?php echo $base_url; ?>assets/js/libs/jquery/fullcalendar.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="<?php echo $base_url; ?>assets/js/backend_calendar.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var GlobalVariables = {
|
||||||
|
'availableProviders' : <?php echo json_encode($available_providers); ?>,
|
||||||
|
'availableServices' : <?php echo json_encode($available_services); ?>,
|
||||||
|
'baseUrl' : <?php echo '"' . $base_url . '"'; ?>
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
BackendCalendar.initialize(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="calendar-page">
|
||||||
|
<div id="calendar-toolbar">
|
||||||
|
<div id="calendar-filter">
|
||||||
|
<label for="select-provider">Provider Calendar</label>
|
||||||
|
<select id="select-provider"></select>
|
||||||
|
<br>
|
||||||
|
<label for="select-service">Service Calendar</label>
|
||||||
|
<select id="select-service"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="calendar-actions">
|
||||||
|
<button id="google-sync" class="btn btn-danger btn-large">
|
||||||
|
<i class="icon-refresh icon-white"></i>
|
||||||
|
Synchronize
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button id="enable-sync" class="btn btn-primary btn-large">
|
||||||
|
<i class="icon-calendar icon-white"></i>
|
||||||
|
Enable Sync
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="calendar"></div>
|
||||||
|
</div>
|
10
src/application/views/backend/footer.php
Normal file
10
src/application/views/backend/footer.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<div id="footer">
|
||||||
|
<div id="footer-content">
|
||||||
|
Powered by <a href="">Easy!Appointments</a> |
|
||||||
|
Copyright © <?php echo date('Y'); ?>
|
||||||
|
<a href="http://www.alextselegidis.com">Alex Tselegidis</a> |
|
||||||
|
Licensed Under GPLv3
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
106
src/application/views/backend/header.php
Normal file
106
src/application/views/backend/header.php
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Easy!Appointments Admin</title>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
<link rel="icon" type="image/x-icon"
|
||||||
|
href="<?php echo $base_url; ?>assets/images/favicon.ico">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// INCLUDE CSS FILES
|
||||||
|
// ------------------------------------------------------------ ?>
|
||||||
|
<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">
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="<?php echo $base_url; ?>assets/css/libs/jquery/jquery-ui.min.css">
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="<?php echo $base_url; ?>assets/css/libs/jquery/jquery.qtip.min.css">
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="<?php echo $base_url; ?>assets/css/backend.css">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// INCLUDE JAVASCRIPT FILES
|
||||||
|
// ------------------------------------------------------------ ?>
|
||||||
|
<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/jquery/jquery-ui.min.js"></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery.qtip.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"
|
||||||
|
src="<?php echo $base_url; ?>assets/js/backend.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<div id="header-logo">
|
||||||
|
<img src="<?php echo $base_url; ?>assets/images/logo.png">
|
||||||
|
<span><?php echo $company_name; ?></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="header-menu">
|
||||||
|
<?php // CALENDAR MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/calendar" class="menu-item">
|
||||||
|
Calendar
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php // CUSTOMERS MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/customers" class="menu-item">
|
||||||
|
Customers
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php // SERVICES MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/services" class="menu-item">
|
||||||
|
Services
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php // PROVIDERS MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/providers" class="menu-item">
|
||||||
|
Providers
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php // SETTINGS MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/settings" class="menu-item">
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php // LOGOUT MENU ITEM
|
||||||
|
// ------------------------------------------------------ ?>
|
||||||
|
<a href="<?php echo $base_url; ?>backend/logout" class="menu-item">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
57
src/assets/css/backend.css
Normal file
57
src/assets/css/backend.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* BACKEND CSS FILE FOR EASY!APPOINTMENTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
root {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BACKEND GENERAL ELEMENTS
|
||||||
|
-------------------------------------------------------------------- */
|
||||||
|
#header {
|
||||||
|
height: 70px;
|
||||||
|
background-color: #35B66F;
|
||||||
|
border-bottom: 6px solid #247A4B;
|
||||||
|
}
|
||||||
|
#header #header-logo { display: inline-block; height: 60px; margin: 10px 15px 0px 15px; }
|
||||||
|
#header #header-logo img { float: left; width: 50px; height: 50px; margin-right: 6px; }
|
||||||
|
#header #header-logo span { float: left; font-size: 20px; color: white; margin-top: 16px; }
|
||||||
|
|
||||||
|
#header #header-menu { display: inline-block; float: right; height: 100%; }
|
||||||
|
#header #header-menu .menu-item { float: left; margin-right: 8px; margin-top: 10px;
|
||||||
|
padding: 15px 12px; min-width: 68px; text-align: center;
|
||||||
|
font-weight: bold; color: #FFF; text-decoration: none;
|
||||||
|
font-size: 16px; }
|
||||||
|
#header #header-menu .menu-item:hover { background-color: #247A4B; }
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
background-color: #F7F7F7;
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
|
}
|
||||||
|
#footer #footer-content { padding: 15px; }
|
||||||
|
|
||||||
|
/* BACKEND CALENDAR PAGE
|
||||||
|
-------------------------------------------------------------------- */
|
||||||
|
#calendar-page #calendar-toolbar { margin: 15px 10px 20px 10px; padding-bottom: 10px;
|
||||||
|
overflow: auto; border-bottom: 1px solid #D6D6D6; }
|
||||||
|
#calendar-page #calendar-filter { display: inline-block; float: left; }
|
||||||
|
#calendar-page #calendar-filter label { display: inline-block; margin-right: 7px;
|
||||||
|
font-weight: bold; font-size: 18px; width: 180px; }
|
||||||
|
#calendar-page #calendar-filter select { margin-top: 5px; }
|
||||||
|
#calendar-page #calendar-actions { display: inline-block; float: right; margin-top: 16px; }
|
||||||
|
#calendar-page #calendar { margin: 12px; }
|
||||||
|
|
||||||
|
/* BACKEND CUSTOMERS PAGE
|
||||||
|
-------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* BACKEND SERVICES PAGE
|
||||||
|
-------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* BACKEND PROVIDERS PAGE
|
||||||
|
-------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* BACKEND SETTINGS PAGE
|
||||||
|
-------------------------------------------------------------------- */
|
579
src/assets/css/libs/jquery/fullcalendar.css
Normal file
579
src/assets/css/libs/jquery/fullcalendar.css
Normal file
|
@ -0,0 +1,579 @@
|
||||||
|
/*!
|
||||||
|
* FullCalendar v1.6.1 Stylesheet
|
||||||
|
* Docs & License: http://arshaw.com/fullcalendar/
|
||||||
|
* (c) 2013 Adam Shaw
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
.fc {
|
||||||
|
direction: ltr;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .fc,
|
||||||
|
.fc table {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc td,
|
||||||
|
.fc th {
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Header
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-header td {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-left {
|
||||||
|
width: 25%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-right {
|
||||||
|
width: 25%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-title {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-title h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-header-space {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-button {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buttons edges butting together */
|
||||||
|
|
||||||
|
.fc-header .fc-button {
|
||||||
|
margin-right: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-corner-right, /* non-theme */
|
||||||
|
.fc-header .ui-corner-right { /* theme */
|
||||||
|
margin-right: 0; /* back to normal */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* button layering (for border precedence) */
|
||||||
|
|
||||||
|
.fc-header .fc-state-hover,
|
||||||
|
.fc-header .ui-state-hover {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-state-down {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-state-active,
|
||||||
|
.fc-header .ui-state-active {
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Content
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-content {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-view {
|
||||||
|
width: 100%; /* needed for view switching (when view is absolute) */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Cell Styles
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-widget-header, /* <th>, usually */
|
||||||
|
.fc-widget-content { /* <td>, usually */
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */
|
||||||
|
background: #fcf8e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
|
||||||
|
background: #bce8f1;
|
||||||
|
opacity: .3;
|
||||||
|
filter: alpha(opacity=30); /* for IE */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Buttons
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-button {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 .6em;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 1.9em;
|
||||||
|
line-height: 1.9em;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default { /* non-theme */
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default.fc-corner-left { /* non-theme */
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default.fc-corner-right { /* non-theme */
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Our default prev/next buttons use HTML entities like ‹ › « »
|
||||||
|
and we'll try to make them look good cross-browser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.fc-text-arrow {
|
||||||
|
margin: 0 .1em;
|
||||||
|
font-size: 2em;
|
||||||
|
font-family: "Courier New", Courier, monospace;
|
||||||
|
vertical-align: baseline; /* for IE7 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-button-prev .fc-text-arrow,
|
||||||
|
.fc-button-next .fc-text-arrow { /* for ‹ › */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* icon (for jquery ui) */
|
||||||
|
|
||||||
|
.fc-button .fc-icon-wrap {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-button .ui-icon {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
margin-top: -50%;
|
||||||
|
*margin-top: 0;
|
||||||
|
*top: -50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
button states
|
||||||
|
borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.fc-state-default {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
|
||||||
|
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
color: #333;
|
||||||
|
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-hover,
|
||||||
|
.fc-state-down,
|
||||||
|
.fc-state-active,
|
||||||
|
.fc-state-disabled {
|
||||||
|
color: #333333;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-hover {
|
||||||
|
color: #333333;
|
||||||
|
text-decoration: none;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
-webkit-transition: background-position 0.1s linear;
|
||||||
|
-moz-transition: background-position 0.1s linear;
|
||||||
|
-o-transition: background-position 0.1s linear;
|
||||||
|
transition: background-position 0.1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-down,
|
||||||
|
.fc-state-active {
|
||||||
|
background-color: #cccccc;
|
||||||
|
background-image: none;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-disabled {
|
||||||
|
cursor: default;
|
||||||
|
background-image: none;
|
||||||
|
opacity: 0.65;
|
||||||
|
filter: alpha(opacity=65);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Global Event Styles
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event {
|
||||||
|
border: 1px solid #3a87ad; /* default BORDER color */
|
||||||
|
background-color: #3a87ad; /* default BACKGROUND color */
|
||||||
|
color: #fff; /* default TEXT color */
|
||||||
|
font-size: .85em;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.fc-event {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.fc-event,
|
||||||
|
.fc-event-draggable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-rtl .fc-event {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-inner {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-time,
|
||||||
|
.fc-event-title {
|
||||||
|
padding: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .ui-resizable-handle {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99999;
|
||||||
|
overflow: hidden; /* hacky spaces (IE6/7) */
|
||||||
|
font-size: 300%; /* */
|
||||||
|
line-height: 50%; /* */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Horizontal Events
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event-hori {
|
||||||
|
border-width: 1px 0;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-ltr .fc-event-hori.fc-event-start,
|
||||||
|
.fc-rtl .fc-event-hori.fc-event-end {
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-ltr .fc-event-hori.fc-event-end,
|
||||||
|
.fc-rtl .fc-event-hori.fc-event-start {
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resizable */
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-e {
|
||||||
|
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||||
|
right: -3px !important;
|
||||||
|
width: 7px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
cursor: e-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-w {
|
||||||
|
top: 0 !important;
|
||||||
|
left: -3px !important;
|
||||||
|
width: 7px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
cursor: w-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-handle {
|
||||||
|
_padding-bottom: 14px; /* IE6 had 0 height */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Reusable Separate-border Table
|
||||||
|
------------------------------------------------------------*/
|
||||||
|
|
||||||
|
table.fc-border-separate {
|
||||||
|
border-collapse: separate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate th,
|
||||||
|
.fc-border-separate td {
|
||||||
|
border-width: 1px 0 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate th.fc-last,
|
||||||
|
.fc-border-separate td.fc-last {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate tr.fc-last th,
|
||||||
|
.fc-border-separate tr.fc-last td {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate tbody tr.fc-first td,
|
||||||
|
.fc-border-separate tbody tr.fc-first th {
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Month View, Basic Week View, Basic Day View
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-grid th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-week-number {
|
||||||
|
width: 22px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-week-number div {
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-day-number {
|
||||||
|
float: right;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-other-month .fc-day-number {
|
||||||
|
opacity: 0.3;
|
||||||
|
filter: alpha(opacity=30); /* for IE */
|
||||||
|
/* opacity with small font can sometimes look too faded
|
||||||
|
might want to set the 'color' property instead
|
||||||
|
making day-numbers bold also fixes the problem */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-day-content {
|
||||||
|
clear: both;
|
||||||
|
padding: 2px 2px 1px; /* distance between events and day edges */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* event styles */
|
||||||
|
|
||||||
|
.fc-grid .fc-event-time {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right-to-left */
|
||||||
|
|
||||||
|
.fc-rtl .fc-grid .fc-day-number {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-rtl .fc-grid .fc-event-time {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Agenda Week View, Agenda Day View
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-agenda table {
|
||||||
|
border-collapse: separate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-days th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-agenda-axis {
|
||||||
|
width: 50px;
|
||||||
|
padding: 0 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-week-number {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-day-content {
|
||||||
|
padding: 2px 2px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make axis border take precedence */
|
||||||
|
|
||||||
|
.fc-agenda-days .fc-agenda-axis {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-days .fc-col0 {
|
||||||
|
border-left-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all-day area */
|
||||||
|
|
||||||
|
.fc-agenda-allday th {
|
||||||
|
border-width: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-allday .fc-day-content {
|
||||||
|
min-height: 34px; /* TODO: doesnt work well in quirksmode */
|
||||||
|
_height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* divider (between all-day and slots) */
|
||||||
|
|
||||||
|
.fc-agenda-divider-inner {
|
||||||
|
height: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-widget-header .fc-agenda-divider-inner {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* slot rows */
|
||||||
|
|
||||||
|
.fc-agenda-slots th {
|
||||||
|
border-width: 1px 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots td {
|
||||||
|
border-width: 1px 0 0;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots td div {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-slot0 th,
|
||||||
|
.fc-agenda-slots tr.fc-slot0 td {
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-minor th,
|
||||||
|
.fc-agenda-slots tr.fc-minor td {
|
||||||
|
border-top-style: dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-minor th.ui-widget-header {
|
||||||
|
*border-top-style: solid; /* doesn't work with background in IE6/7 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Vertical Events
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event-vert {
|
||||||
|
border-width: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert.fc-event-start {
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert.fc-event-end {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-time {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-inner {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
opacity: .25;
|
||||||
|
filter: alpha(opacity=25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
|
||||||
|
.fc-select-helper .fc-event-bg {
|
||||||
|
display: none\9; /* for IE6/7/8. nested opacity filters while dragging don't work */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resizable */
|
||||||
|
|
||||||
|
.fc-event-vert .ui-resizable-s {
|
||||||
|
bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||||
|
width: 100% !important;
|
||||||
|
height: 8px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
line-height: 8px !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
font-family: monospace;
|
||||||
|
text-align: center;
|
||||||
|
cursor: s-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .ui-resizable-resizing { /* TODO: better selector */
|
||||||
|
_overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
32
src/assets/css/libs/jquery/fullcalendar.print.css
Normal file
32
src/assets/css/libs/jquery/fullcalendar.print.css
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*!
|
||||||
|
* FullCalendar v1.6.1 Print Stylesheet
|
||||||
|
* Docs & License: http://arshaw.com/fullcalendar/
|
||||||
|
* (c) 2013 Adam Shaw
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include this stylesheet on your page to get a more printer-friendly calendar.
|
||||||
|
* When including this stylesheet, use the media='print' attribute of the <link> tag.
|
||||||
|
* Make sure to include this stylesheet IN ADDITION to the regular fullcalendar.css.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Events
|
||||||
|
-----------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event {
|
||||||
|
background: #fff !important;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for vertical events */
|
||||||
|
|
||||||
|
.fc-event-bg {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event .ui-resizable-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 7 KiB |
27
src/assets/js/backend.js
Normal file
27
src/assets/js/backend.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Main javascript code for the backend section of Easy!Appointments.
|
||||||
|
*/
|
||||||
|
$(document).ready(function() {
|
||||||
|
$(window).resize(function() {
|
||||||
|
placeFooterToBottom();
|
||||||
|
}).trigger('resize');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place the backend footer always on the bottom of the page.
|
||||||
|
*/
|
||||||
|
function placeFooterToBottom() {
|
||||||
|
var footerHandle = $('#footer');
|
||||||
|
|
||||||
|
if (window.innerHeight > $('body').height()) {
|
||||||
|
footerHandle.css({
|
||||||
|
'position' : 'absolute',
|
||||||
|
'width' : '100%',
|
||||||
|
'bottom' : '0px'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
footerHandle.css({
|
||||||
|
'position' : 'static'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
66
src/assets/js/backend_calendar.js
Normal file
66
src/assets/js/backend_calendar.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* This namespace contains functions that are used by the backend calendar page.
|
||||||
|
*
|
||||||
|
* @namespace Handles the backend calendar page functionality.
|
||||||
|
*/
|
||||||
|
var BackendCalendar = {
|
||||||
|
/**
|
||||||
|
* This function makes the necessary initialization for the default backend
|
||||||
|
* calendar page. If this namespace is used in another page then this function
|
||||||
|
* might not be needed.
|
||||||
|
*
|
||||||
|
* @param {bool} defaultEventHandlers (OPTIONAL = TRUE) Determines whether the
|
||||||
|
* default event handlers will be set for the current page.
|
||||||
|
*/
|
||||||
|
initialize: function(defaultEventHandlers) {
|
||||||
|
if (defaultEventHandlers === undefined) defaultEventHandlers = true;
|
||||||
|
|
||||||
|
// :: INITIALIZE THE DOM ELEMENTS OF THE PAGE
|
||||||
|
$('#calendar').fullCalendar({
|
||||||
|
defaultView : 'basicWeek',
|
||||||
|
height : BackendCalendar.getCalendarHeight(),
|
||||||
|
windowResize : function(view) {
|
||||||
|
$('#calendar').fullCalendar('option', 'height',
|
||||||
|
BackendCalendar.getCalendarHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// :: FILL THE SELECT ELEMENTS OF THE PAGE
|
||||||
|
$.each(GlobalVariables.availableProviders, function(index, provider) {
|
||||||
|
var option = new Option(provider['first_name'] + ' '
|
||||||
|
+ provider['last_name'], provider['id']);
|
||||||
|
$('#select-provider').append(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.each(GlobalVariables.availableServices, function(index, service) {
|
||||||
|
var option = new Option(service['name'], service['id']);
|
||||||
|
$('#select-service').append(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
// :: BIND THE DEFAULT EVENT HANDLERS
|
||||||
|
if (defaultEventHandlers === true) {
|
||||||
|
BackendCalendar.bindEventHandlers();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method binds the default event handlers for the backend calendar
|
||||||
|
* page. If you do not need the default handlers then initialize the page
|
||||||
|
* by setting the "defaultEventHandlers" argument to "false".
|
||||||
|
*/
|
||||||
|
bindEventHandlers: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method calculates the proper calendar height, in order to be displayed
|
||||||
|
* correctly, even when the browser window is resizing.
|
||||||
|
*
|
||||||
|
* @return {int} Returns the calendar element height in pixels.
|
||||||
|
*/
|
||||||
|
getCalendarHeight: function () {
|
||||||
|
var result = window.innerHeight - $('#footer').height() - $('#header').height()
|
||||||
|
- $('#calendar-toolbar').height() - 80; // 80 for fine tuning
|
||||||
|
return (result > 500) ? result : 500; // Minimum height is 500px
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* @class Implements the js part of the appointment booking page.
|
* @class Implements the js part of the appointment booking page.
|
||||||
*/
|
*/
|
||||||
var bookAppointment = {
|
var FrontendBook = {
|
||||||
/**
|
/**
|
||||||
* Determines the functionality of the page.
|
* Determines the functionality of the page.
|
||||||
*
|
*
|
||||||
|
@ -31,7 +31,7 @@ var bookAppointment = {
|
||||||
manageMode = false; // Default Value
|
manageMode = false; // Default Value
|
||||||
}
|
}
|
||||||
|
|
||||||
bookAppointment.manageMode = manageMode;
|
FrontendBook.manageMode = manageMode;
|
||||||
|
|
||||||
// Initialize page's components (tooltips, datepickers etc).
|
// Initialize page's components (tooltips, datepickers etc).
|
||||||
$('.book-step').qtip({
|
$('.book-step').qtip({
|
||||||
|
@ -49,21 +49,21 @@ var bookAppointment = {
|
||||||
minDate : 0,
|
minDate : 0,
|
||||||
defaultDate : Date.today(),
|
defaultDate : Date.today(),
|
||||||
onSelect : function(dateText, instance) {
|
onSelect : function(dateText, instance) {
|
||||||
bookAppointment.getAvailableHours(dateText);
|
FrontendBook.getAvailableHours(dateText);
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bind the event handlers (might not be necessary every time
|
// Bind the event handlers (might not be necessary every time
|
||||||
// we use this class).
|
// we use this class).
|
||||||
if (bindEventHandlers) {
|
if (bindEventHandlers) {
|
||||||
bookAppointment.bindEventHandlers();
|
FrontendBook.bindEventHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the manage mode is true, the appointments data should be
|
// If the manage mode is true, the appointments data should be
|
||||||
// loaded by default.
|
// loaded by default.
|
||||||
if (bookAppointment.manageMode) {
|
if (FrontendBook.manageMode) {
|
||||||
bookAppointment.applyAppointmentData(GlobalVariables.appointmentData,
|
FrontendBook.applyAppointmentData(GlobalVariables.appointmentData,
|
||||||
GlobalVariables.providerData, GlobalVariables.customerData);
|
GlobalVariables.providerData, GlobalVariables.customerData);
|
||||||
} else {
|
} else {
|
||||||
$('#select-service').trigger('change'); // Load the available hours.
|
$('#select-service').trigger('change'); // Load the available hours.
|
||||||
|
@ -82,8 +82,8 @@ var bookAppointment = {
|
||||||
* date - time periods must be updated.
|
* date - time periods must be updated.
|
||||||
*/
|
*/
|
||||||
$('#select-provider').change(function() {
|
$('#select-provider').change(function() {
|
||||||
bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
|
FrontendBook.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,8 +109,8 @@ var bookAppointment = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
|
FrontendBook.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,10 +138,10 @@ var bookAppointment = {
|
||||||
// If we are on the 3rd tab then we will need to validate the user's
|
// If we are on the 3rd tab then we will need to validate the user's
|
||||||
// input before proceeding to the next step.
|
// input before proceeding to the next step.
|
||||||
if ($(this).attr('data-step_index') === '3') {
|
if ($(this).attr('data-step_index') === '3') {
|
||||||
if (!bookAppointment.validateCustomerForm()) {
|
if (!FrontendBook.validateCustomerForm()) {
|
||||||
return; // Validation failed, do not continue.
|
return; // Validation failed, do not continue.
|
||||||
} else {
|
} else {
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +180,10 @@ var bookAppointment = {
|
||||||
$('#available-hours').on('click', '.available-hour', function() {
|
$('#available-hours').on('click', '.available-hour', function() {
|
||||||
$('.selected-hour').removeClass('selected-hour');
|
$('.selected-hour').removeClass('selected-hour');
|
||||||
$(this).addClass('selected-hour');
|
$(this).addClass('selected-hour');
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (bookAppointment.manageMode) {
|
if (FrontendBook.manageMode) {
|
||||||
/**
|
/**
|
||||||
* Event: Cancel Appointment Button "Click"
|
* Event: Cancel Appointment Button "Click"
|
||||||
*
|
*
|
||||||
|
@ -230,7 +230,7 @@ var bookAppointment = {
|
||||||
|
|
||||||
// If the manage mode is true then the appointment's start
|
// If the manage mode is true then the appointment's start
|
||||||
// date should return as available too.
|
// date should return as available too.
|
||||||
var appointmentId = (bookAppointment.manageMode)
|
var appointmentId = (FrontendBook.manageMode)
|
||||||
? GlobalVariables.appointmentData['id'] : undefined;
|
? GlobalVariables.appointmentData['id'] : undefined;
|
||||||
|
|
||||||
var postData = {
|
var postData = {
|
||||||
|
@ -238,7 +238,7 @@ var bookAppointment = {
|
||||||
'provider_id' : $('#select-provider').val(),
|
'provider_id' : $('#select-provider').val(),
|
||||||
'selected_date' : selDate,
|
'selected_date' : selDate,
|
||||||
'service_duration' : selServiceDuration,
|
'service_duration' : selServiceDuration,
|
||||||
'manage_mode' : bookAppointment.manageMode,
|
'manage_mode' : FrontendBook.manageMode,
|
||||||
'appointment_id' : appointmentId
|
'appointment_id' : appointmentId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ var bookAppointment = {
|
||||||
+ '</span><br/>');
|
+ '</span><br/>');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (bookAppointment.manageMode) {
|
if (FrontendBook.manageMode) {
|
||||||
// Set the appointment start time as selected.
|
// Set the appointment start time as selected.
|
||||||
$('.available-hour').removeClass('selected-hour');
|
$('.available-hour').removeClass('selected-hour');
|
||||||
$('.available-hour').filter(function() {
|
$('.available-hour').filter(function() {
|
||||||
|
@ -285,7 +285,7 @@ var bookAppointment = {
|
||||||
$('.available-hour:eq(0)').addClass('selected-hour');
|
$('.available-hour:eq(0)').addClass('selected-hour');
|
||||||
}
|
}
|
||||||
|
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
} else {
|
} else {
|
||||||
$('#available-hours').text('There are no available appointment'
|
$('#available-hours').text('There are no available appointment'
|
||||||
+ 'hours for the selected date. Please choose another '
|
+ 'hours for the selected date. Please choose another '
|
||||||
|
@ -365,15 +365,15 @@ var bookAppointment = {
|
||||||
postData['appointment'] = {
|
postData['appointment'] = {
|
||||||
'start_datetime' : $('#select-date').datepicker('getDate').toString('yyyy-MM-dd')
|
'start_datetime' : $('#select-date').datepicker('getDate').toString('yyyy-MM-dd')
|
||||||
+ ' ' + $('.selected-hour').text() + ':00',
|
+ ' ' + $('.selected-hour').text() + ':00',
|
||||||
'end_datetime' : bookAppointment.calcEndDatetime(),
|
'end_datetime' : FrontendBook.calcEndDatetime(),
|
||||||
'notes' : $('#notes').val(),
|
'notes' : $('#notes').val(),
|
||||||
'id_users_provider' : $('#select-provider').val(),
|
'id_users_provider' : $('#select-provider').val(),
|
||||||
'id_services' : $('#select-service').val()
|
'id_services' : $('#select-service').val()
|
||||||
};
|
};
|
||||||
|
|
||||||
postData['manage_mode'] = bookAppointment.manageMode;
|
postData['manage_mode'] = FrontendBook.manageMode;
|
||||||
|
|
||||||
if (bookAppointment.manageMode) {
|
if (FrontendBook.manageMode) {
|
||||||
postData['appointment']['id'] = GlobalVariables.appointmentData['id'];
|
postData['appointment']['id'] = GlobalVariables.appointmentData['id'];
|
||||||
postData['customer']['id'] = GlobalVariables.customerData['id'];
|
postData['customer']['id'] = GlobalVariables.customerData['id'];
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ var bookAppointment = {
|
||||||
// Set Appointment Date
|
// Set Appointment Date
|
||||||
$('#select-date').datepicker('setDate', Date.parseExact(
|
$('#select-date').datepicker('setDate', Date.parseExact(
|
||||||
appointmentData['start_datetime'], 'yyyy-MM-dd HH:mm:ss'));
|
appointmentData['start_datetime'], 'yyyy-MM-dd HH:mm:ss'));
|
||||||
bookAppointment.getAvailableHours($('#select-date').val());
|
FrontendBook.getAvailableHours($('#select-date').val());
|
||||||
|
|
||||||
// Apply Customer's Data
|
// Apply Customer's Data
|
||||||
$('#last-name').val(customerData['last_name']);
|
$('#last-name').val(customerData['last_name']);
|
||||||
|
@ -445,7 +445,7 @@ var bookAppointment = {
|
||||||
var appointmentNotes = (appointmentData['notes'] !== null) ? appointmentData['notes'] : '';
|
var appointmentNotes = (appointmentData['notes'] !== null) ? appointmentData['notes'] : '';
|
||||||
$('#notes').val(appointmentNotes);
|
$('#notes').val(appointmentNotes);
|
||||||
|
|
||||||
bookAppointment.updateConfirmFrame();
|
FrontendBook.updateConfirmFrame();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch(exc) {
|
} catch(exc) {
|
7
src/assets/js/libs/jquery/fullcalendar.min.js
vendored
Normal file
7
src/assets/js/libs/jquery/fullcalendar.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
107
src/assets/js/libs/jquery/gcal.js
vendored
Normal file
107
src/assets/js/libs/jquery/gcal.js
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*!
|
||||||
|
* FullCalendar v1.6.1 Google Calendar Plugin
|
||||||
|
* Docs & License: http://arshaw.com/fullcalendar/
|
||||||
|
* (c) 2013 Adam Shaw
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
|
||||||
|
var fc = $.fullCalendar;
|
||||||
|
var formatDate = fc.formatDate;
|
||||||
|
var parseISO8601 = fc.parseISO8601;
|
||||||
|
var addDays = fc.addDays;
|
||||||
|
var applyAll = fc.applyAll;
|
||||||
|
|
||||||
|
|
||||||
|
fc.sourceNormalizers.push(function(sourceOptions) {
|
||||||
|
if (sourceOptions.dataType == 'gcal' ||
|
||||||
|
sourceOptions.dataType === undefined &&
|
||||||
|
(sourceOptions.url || '').match(/^(http|https):\/\/www.google.com\/calendar\/feeds\//)) {
|
||||||
|
sourceOptions.dataType = 'gcal';
|
||||||
|
if (sourceOptions.editable === undefined) {
|
||||||
|
sourceOptions.editable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
fc.sourceFetchers.push(function(sourceOptions, start, end) {
|
||||||
|
if (sourceOptions.dataType == 'gcal') {
|
||||||
|
return transformOptions(sourceOptions, start, end);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function transformOptions(sourceOptions, start, end) {
|
||||||
|
|
||||||
|
var success = sourceOptions.success;
|
||||||
|
var data = $.extend({}, sourceOptions.data || {}, {
|
||||||
|
'start-min': formatDate(start, 'u'),
|
||||||
|
'start-max': formatDate(end, 'u'),
|
||||||
|
'singleevents': true,
|
||||||
|
'max-results': 9999
|
||||||
|
});
|
||||||
|
|
||||||
|
var ctz = sourceOptions.currentTimezone;
|
||||||
|
if (ctz) {
|
||||||
|
data.ctz = ctz = ctz.replace(' ', '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, sourceOptions, {
|
||||||
|
url: sourceOptions.url.replace(/\/basic$/, '/full') + '?alt=json-in-script&callback=?',
|
||||||
|
dataType: 'jsonp',
|
||||||
|
data: data,
|
||||||
|
startParam: false,
|
||||||
|
endParam: false,
|
||||||
|
success: function(data) {
|
||||||
|
var events = [];
|
||||||
|
if (data.feed.entry) {
|
||||||
|
$.each(data.feed.entry, function(i, entry) {
|
||||||
|
var startStr = entry['gd$when'][0]['startTime'];
|
||||||
|
var start = parseISO8601(startStr, true);
|
||||||
|
var end = parseISO8601(entry['gd$when'][0]['endTime'], true);
|
||||||
|
var allDay = startStr.indexOf('T') == -1;
|
||||||
|
var url;
|
||||||
|
$.each(entry.link, function(i, link) {
|
||||||
|
if (link.type == 'text/html') {
|
||||||
|
url = link.href;
|
||||||
|
if (ctz) {
|
||||||
|
url += (url.indexOf('?') == -1 ? '?' : '&') + 'ctz=' + ctz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (allDay) {
|
||||||
|
addDays(end, -1); // make inclusive
|
||||||
|
}
|
||||||
|
events.push({
|
||||||
|
id: entry['gCal$uid']['value'],
|
||||||
|
title: entry['title']['$t'],
|
||||||
|
url: url,
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
allDay: allDay,
|
||||||
|
location: entry['gd$where'][0]['valueString'],
|
||||||
|
description: entry['content']['$t']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var args = [events].concat(Array.prototype.slice.call(arguments, 1));
|
||||||
|
var res = applyAll(success, this, args);
|
||||||
|
if ($.isArray(res)) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// legacy
|
||||||
|
fc.gcalFeed = function(url, sourceOptions) {
|
||||||
|
return $.extend({}, sourceOptions, { url: url, dataType: 'gcal' });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
Loading…
Reference in a new issue