Bladeren bron

Add appt. implementation v1

Vijayakrishnan 4 jaren geleden
bovenliggende
commit
5bf1c14feb
2 gewijzigde bestanden met toevoegingen van 235 en 10 verwijderingen
  1. 24 0
      public/css/style.css
  2. 211 10
      resources/views/app/patient/appointment-calendar.blade.php

+ 24 - 0
public/css/style.css

@@ -861,6 +861,9 @@ body .node input[type="number"] {
     margin: 0 auto;
     padding: 0.75rem;
 }
+.stag-popup.stag-popup-sm>form {
+    max-width: 500px;
+}
 .no-scroll {
     /*overflow: hidden;*/
 }
@@ -911,6 +914,27 @@ span.pro-selection {
     padding: 0 !important;
     overflow: hidden !important;
 }
+span.select2-container.select2-container--default.select2-container--open {
+    z-index: 999999;
+}
 .fc .fc-highlight {
     background: rgba(188, 232, 241, 0.6) !important;
 }
+.fc .add-overlay {
+    padding: 1px 4px;
+    display: inline-block;
+    font-weight: bold;
+}
+.fc .add-overlay.add-overlay-day-grid {
+    padding: 4px;
+}
+.stag-popup .stag-popup-title {
+    border-bottom: 1px solid #eee;
+    padding-bottom: 0.75rem;
+    margin-bottom: 1rem;
+    display: flex;
+    align-items: center;
+}
+.stag-popup .stag-popup-title>span {
+    font-size: 17px;
+}

+ 211 - 10
resources/views/app/patient/appointment-calendar.blade.php

@@ -87,27 +87,156 @@
             </form>
             <hr class="my-2">
             <div class="appt-calendar-col">
-                <div class="stag-fc-container">
-
-                </div>
+                <div class="stag-fc-container"></div>
             </div>
         </div>
+        <div class="stag-popup stag-popup-sm mcp-theme-1" stag-popup-key="client-add-appointment">
+            <form method="POST" action="/api/appointment/create" id="newApptForm">
+                <h3 class="stag-popup-title">
+                    <span>Book New Appointment</span>
+                    <a href="#" class="ml-auto text-secondary"
+                       onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
+                </h3>
+                <input type="hidden" name="clientUid" :value="newAppointment.clientUid">
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Patient
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="text"
+                               class="form-control form-control-sm"
+                               :value="client.nameStr" readonly>
+                    </div>
+                </div>
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Pro
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <select id="addApptPro" name="proUid" required
+                                v-model="newAppointment.proUid"
+                                class="form-control form-control-sm">
+                            @foreach($pros as $iPro)
+                                <option value="{{$iPro->uid}}">
+                                    {{$iPro->displayName()}}
+                                </option>
+                            @endforeach
+                        </select>
+                    </div>
+                </div>
+                <input type="hidden" name="referringProUid" value="{{ $pro->uid }}">
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Date
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="date" name="date" required
+                               class="form-control form-control-sm"
+                               v-model="newAppointment.date">
+                    </div>
+                </div>
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Start Time
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="time" name="startTime" required
+                               class="form-control form-control-sm"
+                               v-model="newAppointment.startTime">
+                    </div>
+                </div>
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        End Time
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="time" name="endTime"
+                               class="form-control form-control-sm"
+                               v-model="newAppointment.endTime">
+                    </div>
+                </div>
+                <input type="hidden" name="timeZone" :value="timezone">
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Timezone
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="text"
+                               class="form-control form-control-sm"
+                               :value="timezone" readonly>
+                    </div>
+                </div>
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Title
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <input type="text" name="title"
+                               class="form-control form-control-sm"
+                               v-model="newAppointment.title">
+                    </div>
+                </div>
+                <div class="row mb-2">
+                    <div class="col-3 text-secondary">
+                        Description
+                    </div>
+                    <div class="col-9 font-weight-bold">
+                        <textarea name="description"
+                                  class="form-control form-control-sm"
+                                  v-model="newAppointment.description"></textarea>
+                    </div>
+                </div>
+                <div class="d-flex align-items-center justify-content-center">
+                    <button class="btn btn-sm btn-primary mr-2"
+                            :disabled="inProgress"
+                            v-on:click.prevent="addAppointment()">Submit</button>
+                    <button class="btn btn-sm btn-default border"
+                            onclick="return closeStagPopup()">Cancel</button>
+                </div>
+            </form>
+        </div>
+        <div class="stag-popup mcp-theme-1" stag-popup-key="client-edit-appointment">
+            <form method="POST" action="/api/appointment/update">
+            Edit
+            </form>
+        </div>
     </div>
     <script>
         (function() {
 
+            <?php
+            $patient->nameStr = $patient->displayName();
+            $clientObject = json_encode($patient);
+            ?>
+
             function init() {
                 window.calendarApp = new Vue({
                     el: '#calendarApp',
                     data: {
+                        client: {!! json_encode($patient) !!},
+
                         calendar: null,
                         proMeta: {!! json_encode($proMeta) !!},
                         proIds: ['{{ $pro->id }}'],
                         timezone: 'EASTERN',
+                        today: new Date('{{ date('Y-m-d 00:00:00') }}'),
 
                         // user clicks/selection
                         selectedSlot: null,
                         selectedEvent: null,
+
+                        // new appt.
+                        newAppointment: {
+                            proUid: '',
+                            referringProUid: '',
+                            date: '',
+                            startTime: '',
+                            endTime: '',
+                            timeZone: '',
+                            title: '',
+                            description: '',
+                        },
+                        inProgress: false
                     },
                     methods: {
                         // init
@@ -164,6 +293,16 @@
                                     self.proIds = $(this).val();
                                     self.refreshEvents();
                                 });
+                            $('#addApptPro')
+                                .select2({
+                                    width: '100%',
+                                    templateResult: function(_state) {
+                                        return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
+                                    }
+                                })
+                                .on('change', function() {
+                                    self.newAppointment.proUid = $(this).val();
+                                });
                         },
                         initCalendar: function () {
                             let self = this;
@@ -217,6 +356,7 @@
                                 },
                                 eventClick: function(info) {
                                     self.selectedEvent = info.event;
+                                    self.showEditAppointmentModal();
                                 },
                                 selectAllow: function(info) { // allow only single selections
                                     let seconds = info.end.getTime() - info.start.getTime(),
@@ -229,22 +369,36 @@
                                 },
                                 select: function(info) {
                                     self.selectedSlot = info;
+                                    if(self.today.getTime() <= self.selectedSlot.start.getTime()) {
+                                        $('<a href="#" class="add-overlay ' +
+                                            (info.allDay ? 'add-overlay-day-grid' : 'add-overlay-time-grid') + '">Add</a>')
+                                            .on('mousedown', function() {
+                                                self.showAddAppointmentModal();
+                                                return false;
+                                            })
+                                            .appendTo('.fc-highlight');
+                                    }
                                 },
                                 eventDrop: self.eventMovedOrResized,
                                 eventResize: self.eventMovedOrResized
                             });
                             this.calendar.render();
                         },
+                        dateStr: function(_dateTime) {
+                            return _dateTime.getFullYear() + "-" +
+                                ("0"+(_dateTime.getMonth()+1)).slice(-2) + "-" +
+                                ("0" + _dateTime.getDate()).slice(-2);
+                        },
+                        timeStr: function(_dateTime) {
+                            return ("0" + _dateTime.getHours()).slice(-2) + ":" +
+                                ("0" + _dateTime.getMinutes()).slice(-2);
+                        },
                         eventMovedOrResized: function (info) {
-                            let date = info.event.start.getFullYear() + "-" +
-                                ("0"+(info.event.start.getMonth()+1)).slice(-2) + "-" +
-                                ("0" + info.event.start.getDate()).slice(-2);
-                            let startTime = ("0" + info.event.start.getHours()).slice(-2) + ":" +
-                                ("0" + info.event.start.getMinutes()).slice(-2);
+                            let date = this.dateStr(info.event.start);
+                            let startTime = this.timeStr(info.event.start);
                             let endTime = null;
                             if(info.event.end) {
-                                endTime = ("0" + info.event.end.getHours()).slice(-2) + ":" +
-                                    ("0" + info.event.end.getMinutes()).slice(-2);
+                                endTime = this.timeStr(info.event.end);
                             }
                             $.post('/api/appointment/updateDateAndTime', {
                                 uid: info.event.extendedProps.appointmentUid,
@@ -258,6 +412,53 @@
                         },
                         refreshEvents: function() {
                             this.calendar.refetchEvents();
+                        },
+                        showAddAppointmentModal: function() {
+                            // setup model data
+                            let startTime = this.timeStr(this.selectedSlot.start);
+                            this.newAppointment.clientUid = this.client.uid;
+                            this.newAppointment.proUid = '';
+                            this.newAppointment.referringProUid = '';
+                            this.newAppointment.date = this.dateStr(this.selectedSlot.start);
+                            this.newAppointment.startTime = startTime === '00:00' ? '' : startTime;
+                            this.newAppointment.endTime = '';
+                            this.newAppointment.timeZone = this.timezone;
+                            this.newAppointment.title = '';
+                            this.newAppointment.description = '';
+                            Vue.nextTick(function() {
+                                $('#addApptPro').find('option').prop('selected', false);
+                                $('#addApptPro').trigger('change');
+                                showStagPopup('client-add-appointment');
+                            });
+                        },
+                        addAppointment: function() {
+                            let form = $('#newApptForm');
+                            if(!form[0].checkValidity()) {
+                                form[0].reportValidity();
+                                return false;
+                            }
+                            this.inProgress = true;
+                            let self = this;
+                            showMask();
+                            $.post(form.attr('action'), form.serialize(), function(_data) {
+                                if(_data) {
+                                    if(_data.success) {
+                                        self.refreshEvents();
+                                        closeStagPopup();
+                                    }
+                                    else {
+                                        toastr.error(_data.message);
+                                    }
+                                }
+                                else {
+                                    toastr.error('Unable to book appointment!');
+                                }
+                                self.inProgress = false;
+                                hideMask();
+                            }, 'json');
+                        },
+                        showEditAppointmentModal: function() {
+                            showStagPopup('client-edit-appointment');
                         }
                     },
                     mounted: function() {