|
@@ -0,0 +1,329 @@
|
|
|
|
+<div class="mt-2 pb-1">
|
|
|
|
+ <div class="d-flex align-items-center mb-2 py-2 border-top border-bottom">
|
|
|
|
+ <h6 class="my-0 font-weight-bold text-secondary">Appointments</h6>
|
|
|
|
+ <span class="mx-2 text-secondary">|</span>
|
|
|
|
+ <div moe center>
|
|
|
|
+ <a start show>Add</a>
|
|
|
|
+ <form url="/api/appointment/create" class="mcp-theme-1 add-appt-form">
|
|
|
|
+ <input type="hidden" name="clientUid" value="{{$patient->uid}}">
|
|
|
|
+ <div class="row mb-3">
|
|
|
|
+ <div class="col-6 pr-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Pro *</label>
|
|
|
|
+ <select name="proUid" class="form-control form-control-sm appointment-pro-select"
|
|
|
|
+ required>
|
|
|
|
+ <option value=""> --select-- </option>
|
|
|
|
+ @foreach($pros as $iPro)
|
|
|
|
+ <option
|
|
|
|
+ value="{{$iPro->uid}}" {{ $iPro->uid === $pro->uid ? 'selected' : '' }}>{{$iPro->displayName()}}</option>
|
|
|
|
+ @endforeach
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-6 pl-0">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Timezone *</label>
|
|
|
|
+ <select name="timeZone" class="form-control form-control-sm" required>
|
|
|
|
+ <option value=""> --select-- </option>
|
|
|
|
+ <option value="EASTERN">Eastern</option>
|
|
|
|
+ <option value="CENTRAL">Central</option>
|
|
|
|
+ <option value="MOUNTAIN">Mountain</option>
|
|
|
|
+ <option value="PACIFIC">Pacific</option>
|
|
|
|
+ <option value="ALASKA">Alaska</option>
|
|
|
|
+ <option value="HAWAII">Hawaii</option>
|
|
|
|
+ <option value="PUERTO_RICO">Puerto Rico</option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2 d-flex align-items-start">
|
|
|
|
+ <div class="pro-appointment-calendar flex-grow-0 d-inline-flex justify-content-center"></div>
|
|
|
|
+ <div class="pro-appointment-time-selector pl-1 flex-grow-1 border-left">
|
|
|
|
+ <div class="slot-picker start-time disabled mb-2">
|
|
|
|
+ <table class="table-condensed w-100">
|
|
|
|
+ <thead>
|
|
|
|
+ <tr>
|
|
|
|
+ <th class="prev"></th>
|
|
|
|
+ <th colspan="4" class="datepicker-switch text-center selected-date pb-1">Start Time</th>
|
|
|
|
+ <th class="next"></th>
|
|
|
|
+ </tr>
|
|
|
|
+ </thead>
|
|
|
|
+ <tbody>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="540" data-end="570">9:00</td>
|
|
|
|
+ <td class="slot" data-start="570" data-end="600">9:30</td>
|
|
|
|
+ <td class="slot" data-start="600" data-end="630">10:00</td>
|
|
|
|
+ <td class="slot" data-start="630" data-end="660">10:30</td>
|
|
|
|
+ <td class="slot" data-start="660" data-end="690">11:00</td>
|
|
|
|
+ <td class="slot" data-start="690" data-end="720">11:30</td>
|
|
|
|
+ </tr>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="720" data-end="750">12:00</td>
|
|
|
|
+ <td class="slot" data-start="750" data-end="780">12:30</td>
|
|
|
|
+ <td class="slot" data-start="780" data-end="810">13:00</td>
|
|
|
|
+ <td class="slot" data-start="810" data-end="840">13:30</td>
|
|
|
|
+ <td class="slot" data-start="840" data-end="870">14:00</td>
|
|
|
|
+ <td class="slot" data-start="870" data-end="900">14:30</td>
|
|
|
|
+ </tr>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="900" data-end="930">15:00</td>
|
|
|
|
+ <td class="slot" data-start="930" data-end="960">15:30</td>
|
|
|
|
+ <td class="slot" data-start="960" data-end="990">16:00</td>
|
|
|
|
+ <td class="slot" data-start="990" data-end="1020">16:30</td>
|
|
|
|
+ <td class="slot" data-start="1020" data-end="1050">17:00</td>
|
|
|
|
+ <td class="slot" data-start="1050" data-end="1080">17:30</td>
|
|
|
|
+ </tr>
|
|
|
|
+ </table>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="slot-picker end-time disabled">
|
|
|
|
+ <table class="table-condensed w-100">
|
|
|
|
+ <thead>
|
|
|
|
+ <tr>
|
|
|
|
+ <th class="prev"></th>
|
|
|
|
+ <th colspan="4" class="datepicker-switch text-center selected-date pb-1">End Time</th>
|
|
|
|
+ <th class="next"></th>
|
|
|
|
+ </tr>
|
|
|
|
+ </thead>
|
|
|
|
+ <tbody>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="540" data-end="570">9:30</td>
|
|
|
|
+ <td class="slot" data-start="570" data-end="600">10:00</td>
|
|
|
|
+ <td class="slot" data-start="600" data-end="630">10:30</td>
|
|
|
|
+ <td class="slot" data-start="630" data-end="660">11:00</td>
|
|
|
|
+ <td class="slot" data-start="660" data-end="690">11:30</td>
|
|
|
|
+ <td class="slot" data-start="690" data-end="720">12:00</td>
|
|
|
|
+ </tr>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="720" data-end="750">12:30</td>
|
|
|
|
+ <td class="slot" data-start="750" data-end="780">13:00</td>
|
|
|
|
+ <td class="slot" data-start="780" data-end="810">13:30</td>
|
|
|
|
+ <td class="slot" data-start="810" data-end="840">14:00</td>
|
|
|
|
+ <td class="slot" data-start="840" data-end="870">14:30</td>
|
|
|
|
+ <td class="slot" data-start="870" data-end="900">15:00</td>
|
|
|
|
+ </tr>
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="slot" data-start="900" data-end="930">15:30</td>
|
|
|
|
+ <td class="slot" data-start="930" data-end="960">16:00</td>
|
|
|
|
+ <td class="slot" data-start="960" data-end="990">16:30</td>
|
|
|
|
+ <td class="slot" data-start="990" data-end="1020">17:00</td>
|
|
|
|
+ <td class="slot" data-start="1020" data-end="1050">17:30</td>
|
|
|
|
+ <td class="slot" data-start="1050" data-end="1080">18:00</td>
|
|
|
|
+ </tr>
|
|
|
|
+ </table>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ {{--<div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Date *</label>
|
|
|
|
+ <input type="date" name="date" min="{{ date('Y-m-d') }}" value="{{ date('Y-m-d') }}"
|
|
|
|
+ class="form-control form-control-sm" required>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Start Time *</label>
|
|
|
|
+ <input type="time" name="startTime" class="form-control form-control-sm" required>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">End Time *</label>
|
|
|
|
+ <input type="time" name="endTime" class="form-control form-control-sm" required>
|
|
|
|
+ </div>--}}
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Title</label>
|
|
|
|
+ <input type="text" name="title" class="form-control form-control-sm">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm mb-1">Description</label>
|
|
|
|
+ <textarea name="description" class="form-control form-control-sm"></textarea>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
|
|
|
|
+ <button cancel class="btn btn-sm btn-default border">Cancel</button>
|
|
|
|
+ </div>
|
|
|
|
+ </form>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <table class="table table-sm border-0 my-0 mx-2">
|
|
|
|
+ <tbody>
|
|
|
|
+ @foreach($patient->appointments as $appointment)
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="text-black p-0 border-0">
|
|
|
|
+ <div class="pb-0">
|
|
|
|
+ <div relative moe>
|
|
|
|
+ <a class="on-hover-opaque" start show title="Update">
|
|
|
|
+ <i class="font-size-11 fa fa-edit text-primary"></i>
|
|
|
|
+ </a>
|
|
|
|
+ <form url="/api/appointment/update">
|
|
|
|
+ <input type="hidden" name="uid" value="{{ $appointment->uid }}">
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Pro</label>
|
|
|
|
+ <select name="proUid" class="form-control form-control-sm">
|
|
|
|
+ <option value=""> --select-- </option>
|
|
|
|
+ @foreach($pros as $iPro)
|
|
|
|
+ <option
|
|
|
|
+ <?= $appointment->pro->uid === $iPro->uid ? 'selected' : '' ?>
|
|
|
|
+ value="{{$iPro->uid}}">{{$iPro->displayName()}}</option>
|
|
|
|
+ @endforeach
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Date</label>
|
|
|
|
+ <input autofocus type="date" name="date" min="{{ date('Y-m-d') }}"
|
|
|
|
+ value="{{ date("Y-m-d", strtotime($appointment->raw_date)) }}"
|
|
|
|
+ class="form-control form-control-sm">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Start Time</label>
|
|
|
|
+ <input type="time" name="startTime"
|
|
|
|
+ class="form-control form-control-sm"
|
|
|
|
+ value="{{ date("H:i", strtotime($appointment->raw_start_time)) }}">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">End Time</label>
|
|
|
|
+ <input type="time" name="endTime"
|
|
|
|
+ class="form-control form-control-sm"
|
|
|
|
+ value="{{ date("H:i", strtotime($appointment->raw_end_time)) }}">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Timezone *</label>
|
|
|
|
+ <select name="timeZone" class="form-control form-control-sm"
|
|
|
|
+ required>
|
|
|
|
+ <option value=""> --select-- </option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'EASTERN' ? 'selected' : '' }} value="EASTERN">Eastern</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'CENTRAL' ? 'selected' : '' }} value="CENTRAL">Central</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'MOUNTAIN' ? 'selected' : '' }} value="MOUNTAIN">Mountain</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'PACIFIC' ? 'selected' : '' }} value="PACIFIC">Pacific</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'ALASKA' ? 'selected' : '' }} value="ALASKA">Alaska</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'HAWAII' ? 'selected' : '' }} value="HAWAII">Hawaii</option>
|
|
|
|
+ <option
|
|
|
|
+ {{ $appointment->timezone === 'PUERTO_RICO' ? 'selected' : '' }} value="PUERTO_RICO">Puerto Rico</option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Title</label>
|
|
|
|
+ <input type="text" name="title" class="form-control form-control-sm"
|
|
|
|
+ value="{{ $appointment->title }}">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mb-2">
|
|
|
|
+ <label class="text-secondary text-sm">Description</label>
|
|
|
|
+ <textarea name="description"
|
|
|
|
+ class="form-control form-control-sm">{{ $appointment->description }}</textarea>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
|
|
|
|
+ <button cancel class="btn btn-sm btn-default border">Cancel</button>
|
|
|
|
+ </div>
|
|
|
|
+ </form>
|
|
|
|
+ </div>
|
|
|
|
+ {{ friendly_date_time($appointment->raw_date, false) }}
|
|
|
|
+ @if($appointment->raw_start_time)
|
|
|
|
+ , {{ friendly_time($appointment->raw_start_time, false) }}
|
|
|
|
+ @endif
|
|
|
|
+ @if($appointment->timezone)
|
|
|
|
+ <span class="text-secondary text-sm">({{ $appointment->timezone }})</span>
|
|
|
|
+ @endif
|
|
|
|
+ /
|
|
|
|
+ {{--<span class="d-inline-block ml- 2 text-secondary">{{ $appointment->title }}</span>
|
|
|
|
+ / --}}
|
|
|
|
+ <b class="mr-1">{{$appointment->pro->displayName()}}</b>
|
|
|
|
+ <span class="text-secondary text-sm">({{ $appointment->status }})</span>
|
|
|
|
+ </div>
|
|
|
|
+ </td>
|
|
|
|
+ </tr>
|
|
|
|
+ @endforeach
|
|
|
|
+ @if(!$patient->appointments || count($patient->appointments) === 0)
|
|
|
|
+ <tr>
|
|
|
|
+ <td class="text-secondary p-0 border-0">
|
|
|
|
+ No appointments
|
|
|
|
+ </td>
|
|
|
|
+ </tr>
|
|
|
|
+ @endif
|
|
|
|
+ </tbody>
|
|
|
|
+ </table>
|
|
|
|
+</div>
|
|
|
|
+<script>
|
|
|
|
+ (function() {
|
|
|
|
+ let selectedStart = false, booked = false;
|
|
|
|
+ function toMinutes(_s, _backTrack) {
|
|
|
|
+ _s = _s.split(':');
|
|
|
|
+ let mins = (+_s[0]) * 60 + +_s[1];
|
|
|
|
+ if(_backTrack) mins -= mins % 30;
|
|
|
|
+ return mins;
|
|
|
|
+ }
|
|
|
|
+ function markBookedSlots(_parent) {
|
|
|
|
+ _parent.find('.slot').removeClass('blocked').removeClass('selected');
|
|
|
|
+ for(let i=0; i<booked.length; i++) {
|
|
|
|
+ let startSlot = false;
|
|
|
|
+ _parent.find('.slot').each(function() {
|
|
|
|
+ let slot = $(this), slotStart = +slot.attr('data-start');
|
|
|
|
+ if(booked[i].start === slotStart) {
|
|
|
|
+ startSlot = slot.addClass('blocked');
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ if(startSlot && startSlot.length) {
|
|
|
|
+ startSlot = startSlot.next();
|
|
|
|
+ }
|
|
|
|
+ if(startSlot && startSlot.length) {
|
|
|
|
+ while(+startSlot.attr('data-start') < booked[i].end) {
|
|
|
|
+ startSlot.addClass('blocked');
|
|
|
|
+ startSlot = startSlot.next();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(_parent.is('.end-time')) {
|
|
|
|
+ let startSlot = _parent.find('.slot').first();
|
|
|
|
+ _parent.find('.slot').each(function() {
|
|
|
|
+ if(+$(this).attr('data-start') < selectedStart) {
|
|
|
|
+ $(this).addClass('blocked');
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ function initAppointmentCalendar() {
|
|
|
|
+ let parentForm = $('.add-appt-form');
|
|
|
|
+ var calendarElem = parentForm.find('.pro-appointment-calendar')
|
|
|
|
+ calendarElem.datepicker({
|
|
|
|
+ format: 'yyyy-mm-dd'
|
|
|
|
+ });
|
|
|
|
+ calendarElem.on('changeDate', function () {
|
|
|
|
+ console.log(calendarElem.datepicker('getFormattedDate'));
|
|
|
|
+
|
|
|
|
+ // parentForm.find('.selected-date').text(calendarElem.datepicker('getFormattedDate'));
|
|
|
|
+ parentForm.find('.slot-picker.start-time').removeClass('disabled');
|
|
|
|
+ let params = 'proUid={{ $pro->uid }}&' +
|
|
|
|
+ 'timeZone=' + parentForm.find('[name="timeZone"]').val() + '&' +
|
|
|
|
+ 'localDate=' + calendarElem.datepicker('getFormattedDate');
|
|
|
|
+ $.get('/api/appointment/getBookedTimesForProAndTimezone?' + params, function(_data) {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ selectedStart = 0;
|
|
|
|
+ if(_data.success && _data.data) {
|
|
|
|
+ booked = _data.data;
|
|
|
|
+ for(let i=0; i<booked.length; i++) {
|
|
|
|
+ booked[i].start = toMinutes(booked[i].startTime, true);
|
|
|
|
+ booked[i].end = toMinutes(booked[i].endTime);
|
|
|
|
+ }
|
|
|
|
+ markBookedSlots($('.slot-picker.start-time'), booked);
|
|
|
|
+ markBookedSlots($('.slot-picker.end-time'), booked);
|
|
|
|
+ parentForm.find('.slot-picker.end-time').addClass('disabled');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }, 'json');
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ $(document).on('click', '.slot-picker td:not(.blocked)', function() {
|
|
|
|
+ $(this).closest('.slot-picker').find('td.selected').removeClass('selected');
|
|
|
|
+ $(this).addClass('selected');
|
|
|
|
+ selectedStart = +$(this).attr('data-start');
|
|
|
|
+ let parentForm = $('.add-appt-form');
|
|
|
|
+ if($(this).closest('.slot-picker').is('.start-time')) {
|
|
|
|
+ parentForm.find('.slot-picker.end-time td.selected').removeClass('selected');
|
|
|
|
+ parentForm.find('.slot-picker.end-time').removeClass('disabled');
|
|
|
|
+ markBookedSlots($('.slot-picker.end-time'), booked);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ addMCInitializer('patient-single-appointment-calendar', initAppointmentCalendar);
|
|
|
|
+ })();
|
|
|
|
+</script>
|