guest booking self-management feature + layout fixes
- add manage_token column to bookings (DB migration done) - generate unique token per booking, include manage link in confirmation emails (no/en/hu) - new routes: manage-booking, manage-booking-process, manage-booking-cancel - new views: manage-booking.php, manage-booking-cancelled.php - 24h cutoff enforcement for cancel/modify; emails sent to guest + studio CC - fix manage-booking step 3 float layout (overflow:auto BFC clearfix) - fix booking page time slot overflow: bookingResultsWrapper 378px -> 360px Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,637 @@
|
||||
<?php
|
||||
if($subpage == 'beauty'){
|
||||
include(getcwd().'/application/views/includes/beauty-skeleton-top.php');
|
||||
} else {
|
||||
include(getcwd().'/application/views/includes/barber-skeleton-top.php');
|
||||
}
|
||||
|
||||
$lang = $selectedLang;
|
||||
|
||||
$labels = array(
|
||||
'no' => array(
|
||||
'title' => 'Administrer bestilling',
|
||||
'current' => 'Din nåværende bestilling',
|
||||
'date' => 'Dato',
|
||||
'time' => 'Tid',
|
||||
'worker' => 'Arbeider',
|
||||
'services' => 'Tjenester',
|
||||
'total' => 'Totalpris',
|
||||
'cancel_btn' => 'Avbestill bestillingen',
|
||||
'cancel_confirm' => 'Er du sikker på at du vil avbestille bestillingen?',
|
||||
'modify_title' => 'Endre bestilling',
|
||||
'step1' => 'TRINN 1',
|
||||
'step2' => 'TRINN 2',
|
||||
'step3' => 'TRINN 3',
|
||||
'services_label' => 'Tjenester',
|
||||
'choose_worker' => 'Velg en arbeider',
|
||||
'next' => 'Neste',
|
||||
'back' => 'Tilbake',
|
||||
'send' => 'Bekreft endring',
|
||||
'no_times' => 'Ingen ledige tider denne dagen!',
|
||||
'expired_msg' => 'Denne bestillingen er allerede passert og kan ikke endres.',
|
||||
'cutoff_msg' => 'Bestillingen er innen 24 timer og kan ikke endres eller avbestilles.',
|
||||
),
|
||||
'hu' => array(
|
||||
'title' => 'Foglalás kezelése',
|
||||
'current' => 'Jelenlegi foglalásod',
|
||||
'date' => 'Dátum',
|
||||
'time' => 'Időpont',
|
||||
'worker' => 'Dolgozó',
|
||||
'services' => 'Szolgáltatás(ok)',
|
||||
'total' => 'Összesen',
|
||||
'cancel_btn' => 'Foglalás törlése',
|
||||
'cancel_confirm' => 'Biztosan törölni szeretnéd a foglalást?',
|
||||
'modify_title' => 'Foglalás módosítása',
|
||||
'step1' => '1. LÉPÉS',
|
||||
'step2' => '2. LÉPÉS',
|
||||
'step3' => '3. LÉPÉS',
|
||||
'services_label' => 'Szolgáltatások',
|
||||
'choose_worker' => 'Válassz dolgozót',
|
||||
'next' => 'Tovább',
|
||||
'back' => 'Vissza',
|
||||
'send' => 'Módosítás megerősítése',
|
||||
'no_times' => 'Ezen a napon nincs szabad időpont!',
|
||||
'expired_msg' => 'Ez a foglalás már elmúlt, nem módosítható.',
|
||||
'cutoff_msg' => 'A foglalás 24 órán belül van, nem módosítható vagy törölhető.',
|
||||
),
|
||||
'en' => array(
|
||||
'title' => 'Manage Booking',
|
||||
'current' => 'Your current booking',
|
||||
'date' => 'Date',
|
||||
'time' => 'Time',
|
||||
'worker' => 'Worker',
|
||||
'services' => 'Services',
|
||||
'total' => 'Total price',
|
||||
'cancel_btn' => 'Cancel booking',
|
||||
'cancel_confirm' => 'Are you sure you want to cancel your booking?',
|
||||
'modify_title' => 'Modify booking',
|
||||
'step1' => 'STEP 1',
|
||||
'step2' => 'STEP 2',
|
||||
'step3' => 'STEP 3',
|
||||
'services_label' => 'Services',
|
||||
'choose_worker' => 'Choose a worker',
|
||||
'next' => 'Next',
|
||||
'back' => 'Back',
|
||||
'send' => 'Confirm changes',
|
||||
'no_times' => 'There is no available time on this day!',
|
||||
'expired_msg' => 'This booking has already passed and cannot be modified.',
|
||||
'cutoff_msg' => 'Your booking is within 24 hours and can no longer be changed or cancelled.',
|
||||
),
|
||||
);
|
||||
|
||||
$l = isset($labels[$lang]) ? $labels[$lang] : $labels['en'];
|
||||
?>
|
||||
|
||||
<style>
|
||||
/* ── Manage-booking overrides ───────────────────────────────────────────── */
|
||||
|
||||
/* Navigation buttons: use normal flow instead of position:absolute */
|
||||
#manageForm .bookingButtonContainer {
|
||||
position: static;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 10px 10px;
|
||||
height: auto;
|
||||
}
|
||||
#manageForm .bookingButton,
|
||||
#manageForm .leftButton,
|
||||
#manageForm .rightButton {
|
||||
position: static;
|
||||
}
|
||||
|
||||
/* Worker table: allow natural height for pre-rendered workers */
|
||||
#manageForm .workerTable {
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
/* Step 3: overflow:auto creates a BFC that contains floated children */
|
||||
#manageForm #bookingStep3 {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Summary table */
|
||||
.manage-summary-table {
|
||||
width: 100%;
|
||||
max-width: 540px;
|
||||
margin: 0 auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.manage-summary-table td {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #e0c5bb;
|
||||
vertical-align: top;
|
||||
}
|
||||
.manage-summary-table td:first-child {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
width: 130px;
|
||||
background: #fdf5f2;
|
||||
}
|
||||
.manage-summary-box {
|
||||
background: #fdf5f2;
|
||||
border-radius: 6px;
|
||||
padding: 20px;
|
||||
margin: 15px auto;
|
||||
max-width: 580px;
|
||||
text-align: left;
|
||||
}
|
||||
.manage-summary-title {
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
color: #a5705b;
|
||||
margin-bottom: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.manage-cancel-bar {
|
||||
text-align: center;
|
||||
margin: 20px auto;
|
||||
max-width: 580px;
|
||||
}
|
||||
.manage-cancel-btn {
|
||||
background: #7a3a2a;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 11px 28px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 0.85em;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.manage-cancel-btn:hover {
|
||||
background: #5e2a1a;
|
||||
}
|
||||
.manage-divider {
|
||||
border: none;
|
||||
border-top: 1px solid #d9b8ac;
|
||||
margin: 30px auto;
|
||||
max-width: 580px;
|
||||
}
|
||||
.manage-modify-title {
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: #a5705b;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
/* ─────────────────────────────────────────────────────────────────────── */
|
||||
</style>
|
||||
|
||||
<div class="bookingContainer">
|
||||
<div class="bookingTitle"><?php echo $l['title']; ?></div>
|
||||
|
||||
<?php if($status == 'expired'): ?>
|
||||
<p style="color:#c0392b; text-align:center; margin-top:30px; padding:20px;"><?php echo $l['expired_msg']; ?></p>
|
||||
|
||||
<?php elseif($status == 'cutoff'): ?>
|
||||
<p style="color:#c0392b; text-align:center; margin-top:30px; padding:20px;"><?php echo $l['cutoff_msg']; ?></p>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<!-- Current booking summary -->
|
||||
<div class="manage-summary-box">
|
||||
<div class="manage-summary-title"><?php echo $l['current']; ?></div>
|
||||
<table class="manage-summary-table">
|
||||
<tr>
|
||||
<td><?php echo $l['date']; ?></td>
|
||||
<td><?php echo $booking->booking_date; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $l['time']; ?></td>
|
||||
<td><?php echo date('H:i', strtotime($booking->booking_start_time)); ?> – <?php echo date('H:i', strtotime($booking->booking_finish_time)); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $l['worker']; ?></td>
|
||||
<td><?php echo htmlspecialchars($worker->worker_name); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $l['services']; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$totalPrice = 0;
|
||||
$serviceIds = unserialize($booking->service_ids);
|
||||
if(is_array($serviceIds)){
|
||||
echo '<ul style="margin:0; padding-left:16px;">';
|
||||
foreach($serviceIds as $sid){
|
||||
$svc = $this->Service_model->getServiceById($sid);
|
||||
if($svc){
|
||||
$name = ($lang == 'hu') ? $svc->service_name_hu : (($lang == 'no') ? $svc->service_name_no : $svc->service_name_en);
|
||||
$totalPrice += $svc->service_price;
|
||||
echo '<li>'.htmlspecialchars($name).' — '.$svc->service_price.' kr</li>';
|
||||
}
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $l['total']; ?></td>
|
||||
<td><strong><?php echo $totalPrice; ?> kr</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Cancel -->
|
||||
<div class="manage-cancel-bar">
|
||||
<form method="post" action="<?php echo SITEURL; ?>manage-booking-cancel"
|
||||
onsubmit="return confirm('<?php echo addslashes($l['cancel_confirm']); ?>');">
|
||||
<input type="hidden" name="token" value="<?php echo htmlspecialchars($token); ?>">
|
||||
<input type="hidden" name="lang" value="<?php echo htmlspecialchars($lang); ?>">
|
||||
<button type="submit" class="manage-cancel-btn"><?php echo $l['cancel_btn']; ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr class="manage-divider">
|
||||
|
||||
<!-- Modify section -->
|
||||
<div class="manage-modify-title"><?php echo $l['modify_title']; ?></div>
|
||||
|
||||
<ul class="steps-indicator steps-3">
|
||||
<li>
|
||||
<div class="stepTitleContainer">
|
||||
<div class="stepLine"></div>
|
||||
<div class="stepCircle activeStep" id="stepCircle1"></div>
|
||||
<div class="stepTitle"><?php echo $l['step1']; ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="stepTitleContainer">
|
||||
<div class="stepLine"></div>
|
||||
<div class="stepCircle" id="stepCircle2"></div>
|
||||
<div class="stepTitle"><?php echo $l['step2']; ?></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="stepTitleContainer">
|
||||
<div class="stepCircle" id="stepCircle3"></div>
|
||||
<div class="stepTitle"><?php echo $l['step3']; ?></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="totalPanelContainer">
|
||||
<div id="totalPanel" style="display:none;">
|
||||
<div class="serviceBookingDateContainer">
|
||||
<div id="serviceBookingDate"></div>
|
||||
<div id="serviceBookingTime"></div>
|
||||
</div>
|
||||
<div class="serviceBookingWorkerContainer"></div>
|
||||
<div class="serviceContent"></div>
|
||||
<div class="totalSelectedTime"></div>
|
||||
<div class="totalPrice"></div>
|
||||
</div>
|
||||
<div id="totalPanelBtnContainer">
|
||||
<div id="totalPanelBtn" style="display:none;"><i class="fas fa-caret-right"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="post" action="<?php echo SITEURL; ?>manage-booking-process" id="manageForm">
|
||||
<input type="hidden" name="token" value="<?php echo htmlspecialchars($token); ?>">
|
||||
<input type="hidden" name="lang" value="<?php echo htmlspecialchars($lang); ?>">
|
||||
<input type="hidden" name="subpage" value="<?php echo htmlspecialchars($subpage); ?>">
|
||||
<input type="hidden" name="sendBooking" value="1">
|
||||
|
||||
<!-- Step 1: Services -->
|
||||
<div class="BookingStepContainer" id="bookingStep1">
|
||||
<div class="totalTime"><input type="time" id="servicelength" name="servicelength" value="00:00"></div>
|
||||
|
||||
<div class="bookingTable">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading"><?php echo $l['services_label']; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="serviceTable">
|
||||
<div class="serviceHeader">
|
||||
<div class="serviceCol serviceNameCol">Service name</div>
|
||||
<div class="serviceCol"></div>
|
||||
<div class="serviceCol servicePriceCol">Price</div>
|
||||
<div class="serviceCol serviceInfoCol"></div>
|
||||
<div class="serviceCol serviceCheckCol"></div>
|
||||
</div>
|
||||
<?php
|
||||
function manage_canon_cat($s) {
|
||||
$s = html_entity_decode((string)$s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
$s = strip_tags($s);
|
||||
return trim($s);
|
||||
}
|
||||
if(is_array($services) && count($services) > 0){
|
||||
$groups = array();
|
||||
$order = array();
|
||||
foreach($services as $serviceItem){
|
||||
$label = manage_canon_cat($serviceItem->service_category ?? '');
|
||||
if($label === '') $label = 'Other';
|
||||
if(!isset($groups[$label])){ $groups[$label] = array(); $order[] = $label; }
|
||||
$groups[$label][] = $serviceItem;
|
||||
}
|
||||
foreach($order as $label){
|
||||
?>
|
||||
<div class="serviceRow">
|
||||
<div class="serviceCol" style="width:100%"><h4><?php echo htmlspecialchars($label); ?></h4></div>
|
||||
</div>
|
||||
<?php
|
||||
foreach($groups[$label] as $serviceItem){
|
||||
$isChecked = in_array($serviceItem->service_id, $selectedServiceIds);
|
||||
?>
|
||||
<div class="serviceRow">
|
||||
<div class="serviceCol serviceNameCol" id="serviceName_<?php echo $serviceItem->service_id; ?>">
|
||||
<?php echo htmlspecialchars($serviceItem->service_name); ?>
|
||||
</div>
|
||||
<div class="serviceCol">
|
||||
<input type="time" class="serviceTime" id="time_<?php echo $serviceItem->service_id; ?>" value="<?php echo $serviceItem->service_time; ?>"/>
|
||||
</div>
|
||||
<div class="serviceCol servicePriceCol" id="servicePrice_<?php echo $serviceItem->service_id; ?>">
|
||||
<?php echo $serviceItem->service_price; ?>
|
||||
</div>
|
||||
<div class="serviceCol serviceInfoCol">
|
||||
<div class="serviceInfoIcon">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<div class="serviceInfoLabel"><?php echo htmlspecialchars($serviceItem->service_description); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="serviceCol serviceCheckCol">
|
||||
<input type="hidden" name="service_<?php echo $serviceItem->service_id; ?>" value="0"/>
|
||||
<input type="checkbox"
|
||||
class="service <?php echo $serviceItem->serv_cat_slug; ?>"
|
||||
id="<?php echo $serviceItem->service_id; ?>"
|
||||
name="service_<?php echo $serviceItem->service_id; ?>"
|
||||
value="1"
|
||||
<?php echo $isChecked ? 'checked' : ''; ?>/>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="bookingButtonContainer">
|
||||
<span></span>
|
||||
<input type="button" class="rightButton bookingButton" onclick="goToStep(2);" value="<?php echo $l['next']; ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Worker -->
|
||||
<div class="BookingStepContainer" id="bookingStep2" style="display:none;">
|
||||
<input type="hidden" name="worker_id" id="worker_id" value="<?php echo $booking->worker_id; ?>">
|
||||
<div class="bookingHeader"><?php echo $l['choose_worker']; ?></div>
|
||||
<div class="workerTable" id="workerTable">
|
||||
<?php
|
||||
if(is_array($workers)){
|
||||
foreach($workers as $workerItem){
|
||||
$isSelected = ($workerItem->worker_id == $booking->worker_id);
|
||||
?>
|
||||
<label for="worker_<?php echo $workerItem->worker_id; ?>">
|
||||
<div class="profileRow">
|
||||
<div class="profileCell profileRadioBtn">
|
||||
<input type="radio" name="worker_radio" class="workers"
|
||||
id="worker_<?php echo $workerItem->worker_id; ?>"
|
||||
onclick="setWorker(<?php echo $workerItem->worker_id; ?>)"
|
||||
<?php echo $isSelected ? 'checked' : ''; ?>>
|
||||
</div>
|
||||
<div class="profileCell profileImage">
|
||||
<img src="<?php echo SITEURL; ?>assets/img/<?php echo $workerItem->worker_profile_img; ?>" style="width:65px;height:65px;border-radius:50%;object-fit:cover;">
|
||||
</div>
|
||||
<div class="profileCell">
|
||||
<div class="profileName"><?php echo htmlspecialchars($workerItem->worker_name); ?></div>
|
||||
<div class="profileDescription"><?php echo htmlspecialchars($workerItem->worker_info); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="bookingButtonContainer">
|
||||
<input type="button" class="leftButton bookingButton" onclick="goToStep(1);" value="<?php echo $l['back']; ?>"/>
|
||||
<input type="button" class="rightButton bookingButton" onclick="goToStep(3);" value="<?php echo $l['next']; ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: Date & time -->
|
||||
<div class="BookingStepContainer" id="bookingStep3" style="display:none;">
|
||||
<div class="bookingCalendar">
|
||||
<div id="datepicker"></div>
|
||||
</div>
|
||||
<div class="bookingResultsWrapper">
|
||||
<div class="availableTimesContainerTitle"></div>
|
||||
<div class="availableTimesContainer" style="padding:5px;">
|
||||
<input type="hidden" name="booking_date" id="booking_date" value="<?php echo date('Y-m-d'); ?>">
|
||||
<input type="hidden" name="booking_start_time" id="booking_time" value="">
|
||||
<div class="availableTimes"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
<div class="bookingButtonContainer">
|
||||
<input type="button" class="leftButton bookingButton" onclick="goToStep(2);" value="<?php echo $l['back']; ?>"/>
|
||||
<input type="submit" class="rightButton bookingButton" id="sendManageBtn" name="sendBooking" value="<?php echo $l['send']; ?>" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var noTimesMsg = '<?php echo addslashes($l['no_times']); ?>';
|
||||
|
||||
$(document).ready(function(){
|
||||
recalcServices();
|
||||
|
||||
$('#totalPanelBtn').click(function(){
|
||||
if($('#totalPanel').is(':visible')){
|
||||
$('#totalPanelBtn').html('<i class="fas fa-caret-left"></i>');
|
||||
$('#totalPanel').hide();
|
||||
$('#totalPanelBtn').css('border-top-left-radius','5px');
|
||||
$('#totalPanelBtn').css('border-bottom-left-radius','5px');
|
||||
} else {
|
||||
$('#totalPanelBtn').html('<i class="fas fa-caret-right"></i>');
|
||||
$('#totalPanel').show();
|
||||
$('#totalPanelBtn').css('border-top-left-radius','0px');
|
||||
$('#totalPanelBtn').css('border-bottom-left-radius','0px');
|
||||
}
|
||||
});
|
||||
|
||||
$('.service').click(function(){
|
||||
recalcServices();
|
||||
if($('.service').is(':checked')){
|
||||
var selectedClasses = $(this).attr('class');
|
||||
var selectedclassesArray = selectedClasses.split(' ');
|
||||
$('.service').each(function(){
|
||||
var actualElementArray = $(this).attr('class').split(' ');
|
||||
if(selectedclassesArray[1] !== actualElementArray[1]){
|
||||
$(this).attr('disabled', true);
|
||||
}
|
||||
});
|
||||
getAvailableWorkersByServiceCategorySlug(selectedclassesArray[1]);
|
||||
} else {
|
||||
$('.service').attr('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
$('#booking_time').change(function(){
|
||||
if($(this).val() !== ''){
|
||||
$('#sendManageBtn').prop('disabled', false);
|
||||
} else {
|
||||
$('#sendManageBtn').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function recalcServices(){
|
||||
var totalPrice = 0;
|
||||
var classIsChecked = 0;
|
||||
$('#servicelength').val('00:00');
|
||||
var selectedServices = '<div class="selectedServiceTable">';
|
||||
selectedServices += '<div class="totalServiceRow serviceHeader"><div class="selectedServiceCol totalSelectedServiceName">Service name</div><div class="selectedServiceCol totalSelectedServicePrice">Price</div></div>';
|
||||
|
||||
$('.service').each(function(){
|
||||
if($(this).is(':checked')){
|
||||
classIsChecked = 1;
|
||||
var selected_id = $(this).attr('id');
|
||||
var priceEl = document.getElementById('servicePrice_'+selected_id).innerHTML.trim();
|
||||
totalPrice += parseInt(priceEl);
|
||||
var nameEl = document.getElementById('serviceName_'+selected_id).innerHTML.trim();
|
||||
selectedServices += '<div class="totalServiceRow"><div class="selectedServiceCol totalSelectedServiceName">'+nameEl+'</div><div class="selectedServiceCol totalSelectedServicePrice">'+priceEl+' kr</div></div>';
|
||||
|
||||
var currentTotal = $('#servicelength').val();
|
||||
var svcDT = new Date('<?php echo date('Y-m-d'); ?> ' + $('#time_'+selected_id).val());
|
||||
var subH = moment.utc(currentTotal,'HH:mm').add(svcDT.getHours(),'hour').format('HH:mm');
|
||||
var subM = moment.utc(subH,'HH:mm').add(svcDT.getMinutes(),'minutes').format('HH:mm');
|
||||
$('#servicelength').val(subM);
|
||||
}
|
||||
});
|
||||
|
||||
selectedServices += '</div>';
|
||||
$('.serviceContent').html(selectedServices);
|
||||
$('.totalPrice').html('<span class="totalTitle">Total:</span> <span>'+totalPrice+'</span><span class="totalTitle"> kr</span>');
|
||||
$('.totalSelectedTime').html('<span class="totalTitle">Total time:</span> <span>'+$('#servicelength').val()+'</span>');
|
||||
|
||||
if(classIsChecked){
|
||||
$('#totalPanelBtn').show();
|
||||
$('#totalPanel').show();
|
||||
} else {
|
||||
$('#totalPanelBtn').hide();
|
||||
$('#totalPanel').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function getAvailableWorkersByServiceCategorySlug(categorySlug){
|
||||
$.ajax({
|
||||
url: '<?php echo base_url(); ?>ajax',
|
||||
type: 'POST',
|
||||
data: { action: 'getAvailableWorkersByServiceCategory', serv_cat_slug: categorySlug },
|
||||
dataType: 'json',
|
||||
}).done(function(result){
|
||||
$('#workerTable').html(result.workerListShow);
|
||||
if(result.workers && result.workers.length > 0){
|
||||
setWorker(result.workers[0].worker_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function(){
|
||||
$('#datepicker').datepicker({
|
||||
firstDay: 1,
|
||||
defaultDate: new Date(),
|
||||
dateFormat: 'yy-mm-dd',
|
||||
onSelect: function(dateText){
|
||||
$('#booking_date').val(this.value);
|
||||
$('#sendManageBtn').prop('disabled', true);
|
||||
$('#booking_time').val('');
|
||||
getAvailableTimesOfTheDay(this.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getAvailableTimesOfTheDay(selectedDate){
|
||||
$('.bookingResultsWrapper').show();
|
||||
$('#serviceBookingDate').html(selectedDate).show();
|
||||
|
||||
$.ajax({
|
||||
url: '<?php echo base_url(); ?>ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'getAvailableTimes',
|
||||
worker_id: $('#worker_id').val(),
|
||||
servicelength: $('#servicelength').val(),
|
||||
selectedDate: selectedDate
|
||||
},
|
||||
}).done(function(result){
|
||||
if(result != 0){
|
||||
$('.availableTimes').html(result);
|
||||
} else {
|
||||
$('.availableTimes').html(noTimesMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setSelectedTime(time, id){
|
||||
$('#booking_time').val(time).trigger('change');
|
||||
$('#serviceBookingTime').html(time).show();
|
||||
$('.availableBookingTime').removeClass('selectedTime');
|
||||
$('#bookingTime_'+id).addClass('selectedTime');
|
||||
}
|
||||
|
||||
function goToStep(stepNumber){
|
||||
if(canGotoNextStep(stepNumber)){
|
||||
$('.stepCircle').removeClass('activeStep');
|
||||
$('.BookingStepContainer').hide();
|
||||
$('#bookingStep'+stepNumber).show();
|
||||
|
||||
if(stepNumber >= 3){
|
||||
$('#stepCircle1, #stepCircle2, #stepCircle3').addClass('activeStep');
|
||||
if(stepNumber == 3 && $('#datepicker').val() !== ''){
|
||||
getAvailableTimesOfTheDay($('#datepicker').val());
|
||||
}
|
||||
$('.bookingSummaryContainer').show();
|
||||
} else if(stepNumber == 2){
|
||||
$('#stepCircle1, #stepCircle2').addClass('activeStep');
|
||||
$('.bookingResultsWrapper').hide();
|
||||
$('.bookingSummaryContainer').hide();
|
||||
} else {
|
||||
$('#stepCircle1').addClass('activeStep');
|
||||
$('.bookingResultsWrapper').hide();
|
||||
$('.bookingSummaryContainer').hide();
|
||||
}
|
||||
$('html').scrollTop(0);
|
||||
} else {
|
||||
alert('<?php echo ($lang == "no") ? "Vennligst fyll ut de påkrevde feltene!" : (($lang == "hu") ? "Kérjük töltsd ki a kötelező mezőket!" : "Please fill in the required fields!"); ?>');
|
||||
}
|
||||
}
|
||||
|
||||
function canGotoNextStep(stepNumber){
|
||||
if(stepNumber == 1 || stepNumber == 4) return 1;
|
||||
if(stepNumber == 2){
|
||||
var checked = 0;
|
||||
$('.service').each(function(){ if($(this).is(':checked')) checked = 1; });
|
||||
return checked;
|
||||
}
|
||||
if(stepNumber == 3){
|
||||
var checked = 0;
|
||||
$('.workers').each(function(){ if($(this).is(':checked')) checked = 1; });
|
||||
return checked;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
function setWorker(worker_id){
|
||||
$('#worker_id').val(worker_id);
|
||||
$('.serviceBookingWorkerContainer').hide().html('');
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
if($subpage == 'beauty'){
|
||||
include(getcwd().'/application/views/includes/beauty-skeleton-bottom.php');
|
||||
} else {
|
||||
include(getcwd().'/application/views/includes/barber-skeleton-bottom.php');
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user