|
@@ -0,0 +1,355 @@
|
|
|
+@extends ('layouts.patient')
|
|
|
+
|
|
|
+@section('inner-content')
|
|
|
+
|
|
|
+ <?php
|
|
|
+ $palette = [
|
|
|
+ ["bc" => '#522e92', "fc" => "#fff"],
|
|
|
+ ["bc" => '#111e6c', "fc" => "#fff"],
|
|
|
+ ["bc" => '#003152', "fc" => "#fff"],
|
|
|
+ ["bc" => '#1034a6', "fc" => "#fff"],
|
|
|
+ ["bc" => '#0f52ba', "fc" => "#fff"],
|
|
|
+ ["bc" => '#447684', "fc" => "#fff"],
|
|
|
+ ["bc" => '#d86700', "fc" => "#fff"],
|
|
|
+ ["bc" => '#643c07', "fc" => "#fff"],
|
|
|
+ ["bc" => '#ff3f3f', "fc" => "#fff"],
|
|
|
+ ["bc" => '#ffa395', "fc" => "#222"],
|
|
|
+ ["bc" => '#6450ff', "fc" => "#fff"],
|
|
|
+ ["bc" => '#8ec7f4', "fc" => "#222"],
|
|
|
+ ["bc" => '#522e92', "fc" => "#fff"],
|
|
|
+ ["bc" => '#111e6c', "fc" => "#fff"],
|
|
|
+ ["bc" => '#003152', "fc" => "#fff"],
|
|
|
+ ["bc" => '#1034a6', "fc" => "#fff"],
|
|
|
+ ["bc" => '#0f52ba', "fc" => "#fff"],
|
|
|
+ ["bc" => '#447684', "fc" => "#fff"],
|
|
|
+ ["bc" => '#d86700', "fc" => "#fff"],
|
|
|
+ ["bc" => '#643c07', "fc" => "#fff"],
|
|
|
+ ["bc" => '#ff3f3f', "fc" => "#fff"],
|
|
|
+ ["bc" => '#ffa395', "fc" => "#222"],
|
|
|
+ ["bc" => '#6450ff', "fc" => "#fff"],
|
|
|
+ ["bc" => '#8ec7f4', "fc" => "#222"],
|
|
|
+ ];
|
|
|
+ ?>
|
|
|
+
|
|
|
+ <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" />
|
|
|
+ <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
|
|
|
+ <link href='/fullcalendar-5.3.2/lib/main.css' rel='stylesheet' />
|
|
|
+ <script src='/fullcalendar-5.3.2/lib/main.js'></script>
|
|
|
+ <div class="d-flex align-items-center pb-2">
|
|
|
+ <h4 class="font-weight-bold m-0 font-size-16">
|
|
|
+ Calendar for {{ $patient->displayName() }}
|
|
|
+ </h4>
|
|
|
+ </div>
|
|
|
+ <hr class="mt-2 mb-3">
|
|
|
+ <div class="d-flex align-items-start appt-form">
|
|
|
+ {{--<form action="/api/appointment/{{ $appointment && $appointment->uid ? 'update' : 'create' }}" method="post" class="appt-form-col pr-2">
|
|
|
+ @if($appointment && $appointment->uid)
|
|
|
+ <input name="uid" type="hidden" value="{{ $appointment->uid }}">
|
|
|
+ @else
|
|
|
+ <input name="clientUid" type="hidden" value="{{ $patient->uid }}">
|
|
|
+ @endif
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Patient</label>
|
|
|
+ <div class="font-weight-bold">{{ $patient->displayName() }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Pro *</label>
|
|
|
+ <select name="proUid" class="form-control form-control-sm">
|
|
|
+ <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="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Timezone *</label>
|
|
|
+ <select name="timeZone" class="form-control form-control-sm" required>
|
|
|
+ <option value=""> --select-- </option>
|
|
|
+ <option {{ ($appointment && $appointment->timezone === 'EASTERN') || (!$appointment || !$appointment->uid) ? 'selected' : '' }}
|
|
|
+ value="EASTERN">Eastern</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'CENTRAL' ? 'selected' : '' }}
|
|
|
+ value="CENTRAL">Central</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'MOUNTAIN' ? 'selected' : '' }}
|
|
|
+ value="MOUNTAIN">Mountain</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'PACIFIC' ? 'selected' : '' }}
|
|
|
+ value="PACIFIC">Pacific</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'ALASKA' ? 'selected' : '' }}
|
|
|
+ value="ALASKA">Alaska</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'HAWAII' ? 'selected' : '' }}
|
|
|
+ value="HAWAII">Hawaii</option>
|
|
|
+ <option {{ $appointment && $appointment->timezone === 'PUERTO_RICO' ? 'selected' : '' }}
|
|
|
+ value="PUERTO_RICO">Puerto Rico</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Date *</label>
|
|
|
+ <input name="date" class="form-control form-control-sm" type="date"
|
|
|
+ value="{{ $appointment && $appointment->raw_date ? $appointment->raw_date : date('Y-m-d') }}"
|
|
|
+ required>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Start Time *</label>
|
|
|
+ <input name="startTime" class="form-control form-control-sm" type="time"
|
|
|
+ value="{{ $appointment && $appointment->raw_start_time ? $appointment->raw_start_time : '' }}"
|
|
|
+ required>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">End Time</label>
|
|
|
+ <input name="endTime" class="form-control form-control-sm" type="time"
|
|
|
+ value="{{ $appointment && $appointment->raw_end_time ? $appointment->raw_end_time : '' }}">
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Title</label>
|
|
|
+ <input name="title" class="form-control form-control-sm" type="text"
|
|
|
+ value="{{ $appointment && $appointment->title ? $appointment->title : '' }}"
|
|
|
+ placeholder="(optional)">
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="text-secondary mb-1">Description</label>
|
|
|
+ <textarea name="description" class="form-control form-control-sm"
|
|
|
+ type="text"
|
|
|
+ placeholder="(optional)"
|
|
|
+ >{{ $appointment && $appointment->description ? $appointment->description : '' }}</textarea>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <button class="btn btn-sm btn-primary d-block w-100 font-weight-bold apply-appt-button" disabled>
|
|
|
+ @if($appointment && $appointment->uid)
|
|
|
+ Update Appointment
|
|
|
+ @else
|
|
|
+ Book Appointment
|
|
|
+ @endif
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </form>--}}
|
|
|
+ <form class="appt-form-col">
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="mb-1 text-secondary">Show appointments for:</label>
|
|
|
+ <select id="eventPros" name="proUid" class="form-control form-control-sm" multiple>
|
|
|
+ <?php
|
|
|
+ $proIndex = 0;
|
|
|
+ $proMeta = [];
|
|
|
+ ?>
|
|
|
+ @foreach($pros as $iPro)
|
|
|
+ <option value="{{$iPro->uid}}" {{ $iPro->uid === $pro->uid ? 'selected' : '' }}
|
|
|
+ data-bc="{{$palette[$proIndex]["bc"]}}"
|
|
|
+ data-fc="{{$palette[$proIndex]["fc"]}}"
|
|
|
+ data-initials="{{$iPro->initials()}}">
|
|
|
+ {{$iPro->displayName()}}
|
|
|
+ </option>
|
|
|
+ <?php
|
|
|
+ $proMeta[$iPro->uid] = [
|
|
|
+ "bc" => $palette[$proIndex]["bc"],
|
|
|
+ "fc" => $palette[$proIndex]["fc"],
|
|
|
+ "initials" => $iPro->initials()
|
|
|
+ ];
|
|
|
+ $proIndex++;
|
|
|
+ if($proIndex >= count($palette)) $proIndex = 0;
|
|
|
+ ?>
|
|
|
+ @endforeach
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label class="mb-1 text-secondary">Show appointments in:</label>
|
|
|
+ <select id="eventTz" name="timeZone" class="form-control form-control-sm" required>
|
|
|
+ <option value="EASTERN" selected>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>
|
|
|
+ </form>
|
|
|
+ <div class="appt-calendar-col pl-3">
|
|
|
+ <div class="stag-fc-container">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <script>
|
|
|
+ (function() {
|
|
|
+ let calendarObject = null;
|
|
|
+ let proMeta = <?= json_encode($proMeta) ?>;
|
|
|
+ function initSelect2() {
|
|
|
+ $('#eventTz').select2({
|
|
|
+ templateResult: function(_state) {
|
|
|
+ return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ $('#eventPros').select2({
|
|
|
+
|
|
|
+ closeOnSelect: false,
|
|
|
+
|
|
|
+ // dropdown options
|
|
|
+ templateResult: function(_state) {
|
|
|
+ let element = _state.element;
|
|
|
+ if(!element || !element.value) {
|
|
|
+ return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
|
|
|
+ }
|
|
|
+ element = $(element);
|
|
|
+ return $('<span class="mcp-theme-1 pro-option" ' +
|
|
|
+ 'data-initials="' + element.attr('data-initials') + '" ' +
|
|
|
+ 'data-bc="' + element.attr('data-bc') + '" ' +
|
|
|
+ 'data-fc="' + element.attr('data-fc') + '"><span>' +
|
|
|
+ '<span class="pro-option-initials" ' +
|
|
|
+ 'style="background: ' + element.attr('data-bc') + '; color: ' + element.attr('data-fc') + '">' +
|
|
|
+ element.attr('data-initials') + '</span>' +
|
|
|
+ _state.text +
|
|
|
+ '</span></span>');
|
|
|
+ },
|
|
|
+
|
|
|
+ // selected items
|
|
|
+ templateSelection: function(_state) {
|
|
|
+ let element = _state.element;
|
|
|
+ if(!element || !element.value) {
|
|
|
+ return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
|
|
|
+ }
|
|
|
+ element = $(element);
|
|
|
+ return $('<span class="pro-selection" style="background: ' + element.attr('data-bc') + '; color: ' + element.attr('data-fc') + '">' +
|
|
|
+ _state.text + '</span>');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ function initCalendar() {
|
|
|
+ calendarObject = new FullCalendar.Calendar($('.stag-fc-container')[0], {
|
|
|
+ headerToolbar: {
|
|
|
+ left: 'prev,next today',
|
|
|
+ center: 'title',
|
|
|
+ right: 'dayGridMonth,timeGridWeek,timeGridDay'
|
|
|
+ },
|
|
|
+ initialDate: '{{ date('Y-m-d') }}',
|
|
|
+ editable: false,
|
|
|
+ navLinks: true,
|
|
|
+ dayMaxEvents: false,
|
|
|
+ events: function(info, successCallback, failureCallback) {
|
|
|
+ let proUid = $('.appt-form [name="proUid"]').val();
|
|
|
+ if(!proUid || !proUid.length) {
|
|
|
+ successCallback([]); // no events if no pro selected
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let timeZone = $('.appt-form [name="timeZone"]').val();
|
|
|
+ if(!timeZone) {
|
|
|
+ successCallback([]); // no events if no tz selected
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log(proUid)
|
|
|
+ $.get('/api/appointment/getAllAppointmentsForPro' +
|
|
|
+ '?proUid=' + proUid +
|
|
|
+ '&start=' + info.startStr.substr(0, 10) +
|
|
|
+ '&end=' + info.endStr.substr(0, 10) +
|
|
|
+ '&timeZone=' + timeZone, function(_data) {
|
|
|
+ // $.get('/api/appointment/getAllAppointmentsForPro?start=1990-01-01&end=2025-01-01&timeZone=CENTRAL', function(_data) {
|
|
|
+ if(_data && _data.success) {
|
|
|
+ let events = _data.data;
|
|
|
+ for(let e in events) {
|
|
|
+ if(events.hasOwnProperty(e) && proMeta[events[e].proUid]) {
|
|
|
+ // events[e].backgroundColor = 'yellow'; // proMeta[events[e].proUid].bc;
|
|
|
+ events[e].borderColor = proMeta[events[e].proUid].bc;
|
|
|
+ // events[e].textColor = 'yellow'; // proMeta[events[e].proUid].fc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ successCallback(events);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ failureCallback('Unable to fetch appointments!');
|
|
|
+ }
|
|
|
+ }, 'json');
|
|
|
+ },
|
|
|
+ loading: function(bool) {
|
|
|
+
|
|
|
+ },
|
|
|
+ dateClick: function(info) {
|
|
|
+ $('.appt-form td.stag-selected').removeClass('stag-selected');
|
|
|
+ $(info.dayEl).addClass('stag-selected');
|
|
|
+ $('.appt-form [name="date"]').val(info.dateStr.substr(0, 10));
|
|
|
+ $('.apply-appt-button').prop('disabled', false);
|
|
|
+ },
|
|
|
+ eventContent: function(arg) {
|
|
|
+
|
|
|
+ },
|
|
|
+ eventClassNames: function(arg) {
|
|
|
+ {{--@if($appointment && $appointment->uid)
|
|
|
+ if(arg.event.extendedProps.appointmentUid === '{{ $appointment->uid }}') {
|
|
|
+ return ['stag-current-appt'];
|
|
|
+ }
|
|
|
+ @endif--}}
|
|
|
+ }
|
|
|
+ });
|
|
|
+ calendarObject.render();
|
|
|
+
|
|
|
+ }
|
|
|
+ function init() {
|
|
|
+
|
|
|
+ initSelect2();
|
|
|
+ initCalendar();
|
|
|
+
|
|
|
+ $(document).on('change', '.appt-form [name="proUid"], .appt-form [name="timeZone"]', function() {
|
|
|
+ calendarObject.refetchEvents();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).on('change', '.appt-form [name="date"]', function() {
|
|
|
+ $('.appt-form td.stag-selected').removeClass('stag-selected');
|
|
|
+ if(!$(this).val()) return;
|
|
|
+ calendarObject.gotoDate($(this).val());
|
|
|
+ $('.fc-day[data-date="' + $(this).val() + '"]').addClass('stag-selected');
|
|
|
+ });
|
|
|
+
|
|
|
+ $('.appt-form [name="date"]').trigger('change');
|
|
|
+
|
|
|
+ $('form.appt-form-col').on('submit', function() {
|
|
|
+ let form = $(this);
|
|
|
+ if(!form[0].checkValidity()) {
|
|
|
+ form[0].reportValidity();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $('.apply-appt-button').prop('disabled', true);
|
|
|
+ $('.appt-form [name="startTime"]').val($('.appt-form [name="startTime"]').val().substr(0, 5));
|
|
|
+ $('.appt-form [name="endTime"]').val($('.appt-form [name="endTime"]').val().substr(0, 5));
|
|
|
+ $.post(form.attr('action'), form.serialize(), function(_data) {
|
|
|
+ if(_data && _data.success) {
|
|
|
+ toastr.success('Appointment updated successfully');
|
|
|
+ $('.apply-appt-button').prop('disabled', true);
|
|
|
+ calendarObject.refetchEvents();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if(_data && _data.message) {
|
|
|
+ toastr.error(_data.message);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ toastr.error('Unable to update appointment!');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 'json');
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).on('change input paste', '.appt-form-col *', function() {
|
|
|
+ updateCalendarTitle();
|
|
|
+ $('.apply-appt-button').prop('disabled', false);
|
|
|
+ });
|
|
|
+
|
|
|
+ function updateCalendarTitle() {
|
|
|
+ $('.stag-calendar-header-extra').remove();
|
|
|
+ if(!$('.appt-form [name="proUid"]').val() || !$('.appt-form [name="timeZone"]').val()) {
|
|
|
+ $('.fc-toolbar-title').parent().addClass('mb-3').removeClass('text-center');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $('.fc-toolbar-title').parent().removeClass('mb-3').addClass('text-center');
|
|
|
+ }
|
|
|
+ let html = '<div class="stag-calendar-header-extra d-inline-flex">' +
|
|
|
+ '<span class="text-secondary">Pro:</span> ' +
|
|
|
+ '<span class="font-weight-bold mr-4">' + $('.appt-form [name="proUid"] option:selected').text() + '</span>' +
|
|
|
+ '<span class="text-secondary">Times in</span> ' +
|
|
|
+ '<span class="font-weight-bold">' + $('.appt-form [name="timeZone"] option:selected').text() + '</span>' +
|
|
|
+ '</div>';
|
|
|
+ $(html).insertAfter('.fc-toolbar-title');
|
|
|
+ }
|
|
|
+
|
|
|
+ updateCalendarTitle();
|
|
|
+ }
|
|
|
+ addMCInitializer('patient-manage-appointment', init);
|
|
|
+ })();
|
|
|
+ </script>
|
|
|
+@endsection
|