Explorar o código

Appointment confirmation flow UI

Vijayakrishnan %!s(int64=4) %!d(string=hai) anos
pai
achega
b1665267b9

+ 4 - 0
app/Http/Controllers/AppointmentController.php

@@ -283,4 +283,8 @@ class AppointmentController extends Controller
         return json_encode($events);
     }
 
+    public function appointmentConfirmationHistory(Request $request, Appointment $appointment) {
+        return view('app.patient.partials.appointment-confirmation-history', compact('appointment'));
+    }
+
 }

+ 7 - 1
app/Models/Appointment.php

@@ -19,6 +19,12 @@ class Appointment extends Model
     }
 
     public function confirmationRequests() {
-        return $this->hasMany(AppointmentConfirmationRequest::class, 'appointment_id', 'id');
+        return $this->hasMany(AppointmentConfirmationRequest::class, 'appointment_id', 'id')
+            ->orderBy('created_at', 'desc');
+    }
+
+    public function confirmationDecisions() {
+        return $this->hasMany(AppointmentConfirmationDecision::class, 'appointment_id', 'id')
+            ->orderBy('created_at', 'desc');
     }
 }

+ 13 - 0
app/Models/AppointmentConfirmationDecision.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
+# use Illuminate\Database\Eloquent\Model;
+
+class AppointmentConfirmationDecision extends Model
+{
+    protected $table = 'appointment_confirmation_decision';
+
+}

+ 29 - 0
public/css/style.css

@@ -1406,3 +1406,32 @@ button.note-templates-trigger-assessment {
     fill: #888;
     transform: translateY(-18px);
 }
+
+/* appt. confirmation history */
+.appointment-confirmation-history-trigger .appointment-confirmation-history {
+    position: absolute;
+    width: 300px;
+    right: 0;
+    background: #fff;
+    opacity: 0;
+    padding: 0 0.75rem;
+    padding-bottom: 0.5rem;
+    box-shadow: 0 0 2px #999;
+    pointer-events: none;
+    transition: opacity 0.3s ease;
+    z-index: 2;
+}
+.appointment-confirmation-history-trigger:hover .appointment-confirmation-history {
+    opacity: 1;
+    pointer-events: all;
+}
+.on-hover-text-reveal {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+/*.on-hover-text-reveal:hover {
+    white-space: normal;
+    overflow: unset;
+    text-overflow: unset;
+}*/

+ 4 - 0
resources/views/app/patient/appointments.blade.php

@@ -32,6 +32,7 @@
                     <th class="px-2 text-secondary border-bottom-0">Title</th>
                     <th class="px-2 text-secondary border-bottom-0">Description</th>
                     <th class="px-2 text-secondary border-bottom-0">Status</th>
+                    <th class="px-2 text-secondary border-bottom-0">Confirmation</th>
                 </tr>
                 </thead>
                 <tbody>
@@ -46,6 +47,9 @@
                         <td class="px-2">{{ $appointment->title }}</td>
                         <td class="px-2">{{ $appointment->description }}</td>
                         <td class="px-2">{{ $appointment->status }}</td>
+                        <td class="px-2">
+                            @include('app.patient.partials.appointment-confirmation')
+                        </td>
                     </tr>
                 @endforeach
                 </tbody>

+ 23 - 0
resources/views/app/patient/partials/appointment-confirmation-history.blade.php

@@ -0,0 +1,23 @@
+@php
+$cRequests = $appointment->confirmationRequests;
+$cDecisions = $appointment->confirmationDecisions;
+@endphp
+
+@if($cRequests && count($cRequests))
+    <p class="my-2"><b>Requests</b></p>
+    @foreach($cRequests as $cRequest)
+        <div class="bg-light p-1 my-1 border border">
+            <div class="text-nowrap">{{ friendly_date_time($cRequest->created_at) }} to <b>{{ $cRequest->to_sms_number }}</b> (SMS)</div>
+            <div class="text-secondary text-sm on-hover-text-reveal">{{ $cRequest->message }}</div>
+        </div>
+    @endforeach
+@endif
+
+@if($cDecisions && count($cDecisions))
+    <p class="my-2"><b>Decisions</b></p>
+    @foreach($cDecisions as $cDecision)
+        <div class="bg-light p-1 my-1 border border">
+            <b class="{{$cDecision->accepted_or_rejected === 'ACCEPTED' ? 'text-success' : 'text-warning-mellow'}}">{{$cDecision->accepted_or_rejected}}</b> on {{ friendly_date_time($cDecision->created_at) }}
+        </div>
+    @endforeach
+@endif

+ 64 - 0
resources/views/app/patient/partials/appointment-confirmation.blade.php

@@ -0,0 +1,64 @@
+<div class="d-flex">
+    <div class="flex-grow-1">
+        @if($appointment->status === 'CREATED' && !$appointment->latest_confirmation_request_at && !$appointment->latest_confirmation_decision_at)
+            <b class="text-warning-mellow">Not requested yet</b>
+            <div>
+                @include('app.patient.partials.appointment-request-confirmation', ['label' => 'Request Confirmation'])
+            </div>
+        @endif
+        @if($appointment->latest_confirmation_decision_at)
+            @if($appointment->status === 'CONFIRMED')
+                <div class="text-nowrap">
+                    <b class="text-success">{{ucwords($appointment->status)}}</b>
+                    <span class="text-secondary ml-1">on {{friendly_date_time($appointment->latest_confirmation_decision_at)}}</span>
+                </div>
+                <div>
+                    @include('app.patient.partials.appointment-request-confirmation', ['label' => 'Re-request Confirmation'])
+                </div>
+            @elseif($appointment->status === 'REJECTED')
+                <div class="text-nowrap">
+                    <b class="text-warning-mellow">{{ucwords($appointment->status)}}</b>
+                    <span class="text-secondary ml-1">on {{friendly_date_time($appointment->latest_confirmation_decision_at)}}</span>
+                </div>
+                <div>
+                    <a href="/patients/view/{{$patient->uid}}/calendar/{{$appointment->uid}}" class="font-weight-bold">
+                        Re-schedule
+                    </a>
+                </div>
+            @endif
+        @elseif($appointment->latest_confirmation_request_at) {{-- requested but not confirmed yet --}}
+            <div class="text-nowrap">
+                <b class="text-primary">Requested</b>
+                <span class="text-secondary ml-1">on {{friendly_date_time($appointment->latest_confirmation_request_at)}}</span>
+            </div>
+            <div>
+                @include('app.patient.partials.appointment-request-confirmation', ['label' => 'Re-request Confirmation'])
+            </div>
+        @endif
+    </div>
+    @if($appointment->latest_confirmation_request_at || $appointment->latest_confirmation_decision_at)
+        <div class="ml-4 px-2 c-pointer position-relative appointment-confirmation-history-trigger"
+             data-uid="{{$appointment->uid}}">
+            <i class="fa fa-history text-secondary"></i>
+            <div class="appointment-confirmation-history">
+
+            </div>
+        </div>
+    @endif
+</div>
+
+<script>
+    (function() {
+        function init() {
+            $('.appointment-confirmation-history-trigger')
+                .off('mouseenter.appointment-confirmation-history')
+                .on('mouseenter.appointment-confirmation-history', function() {
+                    let container = $(this).find('.appointment-confirmation-history')
+                        .empty()
+                        .append('<span class="text-secondary">Please wait ...</span>');
+                    container.load('/appointment-confirmation-history/' + $(this).attr('data-uid'));
+                });
+        }
+        addMCInitializer('appointment-confirmation', init);
+    }).call(window);
+</script>

+ 14 - 0
resources/views/app/patient/partials/appointment-request-confirmation.blade.php

@@ -0,0 +1,14 @@
+<div moe relative class="">
+    <a href="#" start show class="text-sm font-weight-normal">{{ $label }}</a>
+    <form url="/api/appointment/sendConfirmationRequestViaSms" right>
+        <input type="hidden" name="uid" value="{{ $appointment->uid }}">
+        <div class="mb-2">
+            <label for="" class="text-sm text-secondary mb-1">Cell Number</label>
+            <input type="text" class="form-control form-control-sm" name="toSmsNumber" value="{{$patient->cell_number}}" required>
+        </div>
+        <div>
+            <button submit class="btn btn-sm btn-primary mr-1">Send</button>
+            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+        </div>
+    </form>
+</div>

+ 3 - 0
routes/web.php

@@ -209,6 +209,9 @@ Route::middleware('pro.auth')->group(function () {
     // refresh single ticket
     Route::get('/get-ticket/{ticket}', 'PatientController@getTicket');
 
+
+    Route::get('/appointment-confirmation-history/{appointment}', 'AppointmentController@appointmentConfirmationHistory')->name('appointment-confirmation-history');
+
     // 2-pane outer page housing lhs (practice management) and rhs (video call)
     Route::get('/mc/{fragment?}', 'HomeController@mc')
         ->where('fragment', '.*')