Bladeren bron

RHS patient queue & claiming functionality

Vijayakrishnan 4 jaren geleden
bovenliggende
commit
c6bda2c50a

+ 19 - 0
app/Http/Controllers/PracticeManagementController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use App\Models\AppSession;
 use App\Models\Bill;
 use App\Models\Client;
+use App\Models\McpRequest;
 use App\Models\Note;
 use App\Models\ProRate;
 use App\Models\ProTextShortcut;
@@ -151,4 +152,22 @@ class PracticeManagementController extends Controller
         $client = Client::where('uid', $uid)->first();
         return json_encode(["data" => $client ? $client->opentok_session_id : '']);
     }
+
+    // poll to check if there are patients with active mcp requests
+    public function getPatientsInQueue(Request $request) {
+        $requests = McpRequest::where('is_active', true)->limit(3)->get();
+        $results = [];
+        if($requests && count($requests)) {
+            foreach ($requests as $mcpRequest) {
+                $client = $mcpRequest->client;
+                $results[] = [
+                    "clientUid" => $client->uid,
+                    "name" => $client->displayName(),
+                    "initials" => substr($client->name_first, 0, 1) . substr($client->name_last, 0, 1)
+                ];
+            }
+//            $results = $requests;
+        }
+        return json_encode($results);
+    }
 }

+ 5 - 0
app/Models/McpRequest.php

@@ -8,4 +8,9 @@ class McpRequest extends Model
 {
     protected $table = 'mcp_request';
 
+    public function client()
+    {
+        return $this->hasOne(Client::class, 'id', 'for_client_id');
+    }
+
 }

+ 22 - 0
public/css/style.css

@@ -757,3 +757,25 @@ body .node input[type="number"] {
 .appt-calendar-col {
     flex-grow: 1;
 }
+
+/* call panel */
+#proCallComponent {
+    max-height: calc(100% - 151px);
+}
+.patient-queue {
+    height: 150px;
+    position: absolute;
+    left: 0;
+    width: 100%;
+    bottom: 0;
+}
+.queue-item {
+    width: 100px;
+    padding: 0.5rem;
+    padding-bottom: 0.25rem;
+    text-align: center;
+    cursor: pointer;
+}
+.queue-item:hover {
+    background: aliceblue;
+}

+ 425 - 379
resources/views/app/video/call.blade.php

@@ -80,448 +80,494 @@
 
     </div>
 
-    <script>
+    <div class="border-top patient-queue mcp-theme-1" id="queueComponent">
+        <div class="bg-secondary text-white font-weight-bold text-center py-1">
+            @{{ items.length }} patients in the queue
+        </div>
+        <div class="d-flex align-items-center mt-1">
+            <div v-for="item in items">
+                <div class="queue-item border border-primary rounded mx-1" :title="item.name">
+                    <div class="patient-avatar mb-1 text-dark">@{{ item.initials }}</div>
+                    <div class="font-weight-bold small text-nowrap text-ellipsis">@{{ item.name }}</div>
+                </div>
+                <button class="btn btn-sm btn-primary mt-1 text-white font-weight-bold py-0 mx-auto d-block"
+                        v-on:click.prevent="claim(item.clientUid)">Claim</button>
+            </div>
+        </div>
+    </div>
 
-        new Vue({
-            el: '#proCallComponent',
-            delimiters: ['@{{', '}}'],
-            data: {
-                time: 0,
-                startTime: 0,
-                started: false,
-                client: false,
-                pro: false,
+    <script>
+        (function () {
+            new Vue({
+                el: '#proCallComponent',
+                delimiters: ['@{{', '}}'],
+                data: {
+                    time: 0,
+                    startTime: 0,
+                    started: false,
+                    client: false,
+                    pro: false,
 
-                selfName: '',
-                selfToken: '',
+                    selfName: '',
+                    selfToken: '',
 
-                clientUid: '',
+                    clientUid: '',
 
-                otSessionId: '',
+                    otSessionId: '',
 
-                checkingForNextPatient: false,
-                noNextPatient: false,
+                    checkingForNextPatient: false,
+                    noNextPatient: false,
 
-                otSession: false,
+                    otSession: false,
 
-                selfUserType: 'PRO',
-                selfStreamId: '',
-                noOneElseInCall: true,
-                patientInQueue: false,
+                    selfUserType: 'PRO',
+                    selfStreamId: '',
+                    noOneElseInCall: true,
+                    patientInQueue: false,
 
-                videoActive: false,
+                    videoActive: false,
 
-                heartbeatTimer: false,
+                    heartbeatTimer: false,
 
-                ringer: {{ $pro->is_ring_on ? 'true' : 'false' }},
-            },
-            methods: {
-                toggleRinger: function() {
-                    let self = this, endPoint = this.ringer ? 'turnOffRing' : 'turnOnRing';
-                    $.post('/api/pro/' + endPoint, function(_data) {
-                        if(_data && _data.success) {
-                            self.ringer = !self.ringer;
-                        }
-                        else {
-                            if(_data.message) {
-                                toastr.error(_data.message);
-                            }
-                            else {
-                                toastr.error('Unable to change ringer status');
-                            }
-                        }
-                    }, 'json');
-                },
-                pollForNextPatient: function() {
-                    if(!this.started) {
-                        this.nextPatient(true);
-                    }
+                    ringer: {{ $pro->is_ring_on ? 'true' : 'false' }},
                 },
-                nextPatient: function(_pollOnly = false) {
-                    var self = this;
-                    if(!_pollOnly) this.checkingForNextPatient = true;
-                    $.post('/api/client/getNextClientForVideoVisit', {}, function(_data) {
-                        if(_pollOnly) {
-                            self.patientInQueue = _data.success;
-                        }
-                        else {
-                            self.checkingForNextPatient = false;
-                            if(!_data.success) {
-                                self.noNextPatient = _data.message;
-                                window.setTimeout(function() {
-                                    self.noNextPatient = false;
-                                }, 2000);
-                            }
-                            else {
-                                // get ot session key from client record
-                                self.client = true;
-                                self.clientUid = _data.data;
-                                self.videoActive = true;
-                                self.startOpenTokSession();
+                methods: {
+                    toggleRinger: function () {
+                        let self = this, endPoint = this.ringer ? 'turnOffRing' : 'turnOnRing';
+                        $.post('/api/pro/' + endPoint, function (_data) {
+                            if (_data && _data.success) {
+                                self.ringer = !self.ringer;
+                            } else {
+                                if (_data.message) {
+                                    toastr.error(_data.message);
+                                } else {
+                                    toastr.error('Unable to change ringer status');
+                                }
                             }
+                        }, 'json');
+                    },
+                    pollForNextPatient: function () {
+                        if (!this.started) {
+                            this.nextPatient(true);
                         }
-                    }, 'json');
-                },
-                startOpenTokSession: function() {
-                    var self = this;
-                    self.getOpenTokSessionId(function() {
-                        self.selfName = '{{ $pro->name_display  }}';
-                        $.post('/api/openTok/getClientToken', {
-                            opentokSessionId: self.otSessionId,
-                            data: JSON.stringify({
-                                uid: '{{ $pro->uid  }}',
-                                name: self.selfName,
-                                type: 'PRO'
-                            })
-                        }, function (_data) {
-                            console.log(_data);
-                            self.selfToken = _data.data;
-                            self.initOpenTok();
+                    },
+                    nextPatient: function (_pollOnly = false) {
+                        var self = this;
+                        if (!_pollOnly) this.checkingForNextPatient = true;
+                        $.post('/api/client/getNextClientForVideoVisit', {}, function (_data) {
+                            if (_pollOnly) {
+                                self.patientInQueue = _data.success;
+                            } else {
+                                self.checkingForNextPatient = false;
+                                if (!_data.success) {
+                                    self.noNextPatient = _data.message;
+                                    window.setTimeout(function () {
+                                        self.noNextPatient = false;
+                                    }, 2000);
+                                } else {
+                                    // get ot session key from client record
+                                    self.client = true;
+                                    self.clientUid = _data.data;
+                                    self.videoActive = true;
+                                    self.startOpenTokSession();
+                                }
+                            }
+                        }, 'json');
+                    },
+                    startOpenTokSession: function () {
+                        var self = this;
+                        self.getOpenTokSessionId(function () {
+                            self.selfName = '{{ $pro->name_display  }}';
+                            $.post('/api/openTok/getClientToken', {
+                                opentokSessionId: self.otSessionId,
+                                data: JSON.stringify({
+                                    uid: '{{ $pro->uid  }}',
+                                    name: self.selfName,
+                                    type: 'PRO'
+                                })
+                            }, function (_data) {
+                                console.log(_data);
+                                self.selfToken = _data.data;
+                                self.initOpenTok();
+                            });
                         });
-                    });
-                },
-                timeDisplay: function() {
-                    var seconds = this.time / 1000,
-                        minutes = parseInt(seconds / 60, 10);
-                    seconds = parseInt(seconds % 60, 10);
-                    return minutes + " min, " + seconds + " sec";
-                },
-                hangUp: function() {
-                    if(this.otSession) {
-                        try {
-                            this.otSession.disconnect();
-                        }
-                        catch (e) {
-                            console.log('Was already disconnected.');
+                    },
+                    timeDisplay: function () {
+                        var seconds = this.time / 1000,
+                            minutes = parseInt(seconds / 60, 10);
+                        seconds = parseInt(seconds % 60, 10);
+                        return minutes + " min, " + seconds + " sec";
+                    },
+                    hangUp: function () {
+                        if (this.otSession) {
+                            try {
+                                this.otSession.disconnect();
+                            } catch (e) {
+                                console.log('Was already disconnected.');
+                            }
+                            this.otSession = false;
+                            this.otSessionId = '';
+                            this.started = false;
+                            this.startTime = false;
+                            this.videoActive = false;
+                            // this.client = false;
                         }
-                        this.otSession = false;
-                        this.otSessionId = '';
-                        this.started = false;
-                        this.startTime = false;
-                        this.videoActive = false;
-                        // this.client = false;
-                    }
-                },
-                initOpenTok: function() {
+                    },
+                    initOpenTok: function () {
 
-                    /* fake video feed (temp) */
-                    const randomColour = () => {
-                        return Math.round(Math.random() * 255);
-                    };
-
-                    const canvas = document.createElement('canvas');
-                    canvas.width = 640;
-                    canvas.height = 480;
-                    const ctx = canvas.getContext('2d');
-                    var pos = 100;
-                    window.setInterval(function() {
-                        ctx.clearRect(0, 0, canvas.width, canvas.height);
-                        ctx.font = "20px Georgia";
-                        ctx.fillStyle = `rgb(220, 220, 220)`;
-                        ctx.fillText("Video feed from {{ $pro->name_display }}", 20, pos);
-                        pos += 5;
-                        if(pos > canvas.height) pos = 100;
-                    }, 1000);
+                        /* fake video feed (temp) */
+                        const randomColour = () => {
+                            return Math.round(Math.random() * 255);
+                        };
 
-                    var self = this;
+                        const canvas = document.createElement('canvas');
+                        canvas.width = 640;
+                        canvas.height = 480;
+                        const ctx = canvas.getContext('2d');
+                        var pos = 100;
+                        window.setInterval(function () {
+                            ctx.clearRect(0, 0, canvas.width, canvas.height);
+                            ctx.font = "20px Georgia";
+                            ctx.fillStyle = `rgb(220, 220, 220)`;
+                            ctx.fillText("Video feed from {{ $pro->name_display }}", 20, pos);
+                            pos += 5;
+                            if (pos > canvas.height) pos = 100;
+                        }, 1000);
+
+                        var self = this;
+
+                        var apiKey = '<?= env('TOKBOX_API_KEY', '46678902') ?>';
+                        var sessionId = this.otSessionId;
+                        var token = this.selfToken;
+
+                        // destroy if existing
+                        // self.hangUp();
+
+                        self.otSession = OT.initSession(apiKey, sessionId);
+
+                        // peer connected
+                        self.otSession.on('streamCreated', function streamCreated(event) {
+                            console.log('streamCreated', arguments);
+                            var subscriberOptions = {
+                                insertMode: 'append',
+                                width: '100%',
+                                height: '100%'
+                            };
+
+                            var connectionData = JSON.parse(event.stream.connection.data);
+
+                            // add a div for remove view
+                            var remoteViewID = 'remote-view-' + event.stream.id;
+                            var remoteElem = $('<div id="' + remoteViewID + '" class="remote-view thumb-view" ' +
+                                'data-stream="' + event.stream.id + '" ' +
+                                'data-connection-data="' + event.stream.connection.data + '" ' +
+                                'data-name="' + connectionData.name + '" ' +
+                                'data-type="' + connectionData.type + '"></div>');
+                            remoteElem.appendTo('.thumbs');
+
+                            self.otSession.subscribe(event.stream, remoteViewID, subscriberOptions, self.handleOpenTokError);
+
+                            if (connectionData.type === 'CLIENT') {
+                                self.client = true;
+                            }
 
-                    var apiKey = '<?= env('TOKBOX_API_KEY', '46678902') ?>';
-                    var sessionId = this.otSessionId;
-                    var token = this.selfToken;
+                            if (!self.startTime) {
+                                self.startTime = new Date().getTime();
+                                window.setInterval(function () {
+                                    self.time = new Date().getTime() - self.startTime;
+                                }, 1000);
+                                self.started = true;
+                            }
 
-                    // destroy if existing
-                    // self.hangUp();
+                            self.activateParty(event.stream.id);
 
-                    self.otSession = OT.initSession(apiKey, sessionId);
+                            self.noOneElseInCall = false;
+                        });
 
-                    // peer connected
-                    self.otSession.on('streamCreated', function streamCreated(event) {
-                        console.log('streamCreated', arguments);
-                        var subscriberOptions = {
-                            insertMode: 'append',
-                            width: '100%',
-                            height: '100%'
-                        };
+                        // peer disconnected
+                        self.otSession.on("streamDestroyed", function (event) {
+                            onPeerDisconnection(event, event.stream.connection.data);
+                        });
+                        // self.otSession.on("connectionDestroyed", function(event) {
+                        //     debugger;
+                        //     console.log('connectionDestroyed from ' + event.connection.data);
+                        //     onPeerDisconnection(event, event.connection.data);
+                        // });
+
+                        self.otSession.on("connectionCreated", function (event) {
+                            console.log('connectionCreated');
+                            console.log(event);
+                        });
 
-                        var connectionData = JSON.parse(event.stream.connection.data);
+                        function onPeerDisconnection(event, data) {
+
+                            if (event.stream && $('.full-view[data-stream="' + event.stream.id + '"]').length) {
+                                var allThumbs = $('.thumbs [data-stream]:not([data-stream=""]):not(.disconnected-view):visible');
+                                if (allThumbs.length) {
+                                    $('.thumbs [data-stream]:not([data-stream=""])').each(function () {
+                                        if ($(this).attr('data-stream') !== event.stream.id) {
+                                            self.activateParty($(this).attr('data-stream'));
+                                            return false;
+                                        }
+                                    });
+                                } else {
+                                    self.noOneElseInCall = true;
+                                }
+                            }
 
-                        // add a div for remove view
-                        var remoteViewID = 'remote-view-' + event.stream.id;
-                        var remoteElem = $('<div id="' + remoteViewID + '" class="remote-view thumb-view" ' +
-                            'data-stream="' + event.stream.id + '" ' +
-                            'data-connection-data="' + event.stream.connection.data + '" ' +
-                            'data-name="' + connectionData.name + '" ' +
-                            'data-type="' + connectionData.type + '"></div>');
-                        remoteElem.appendTo('.thumbs');
+                            if (event.stream) {
+                                var remoteViewElem = $('[data-stream="' + event.stream.id + '"]');
+                                remoteViewElem.remove();
+                                // if(remoteViewElem.length) {
+                                //     remoteViewElem.attr('data-stream', '');
+                                //     remoteViewElem.attr('data-connection-data', '');
+                                //     remoteViewElem.attr('data-type', '');
+                                //     remoteViewElem.attr('data-name', '');
+                                // }
+                                // remoteViewElem.addClass('disconnected-view')
+                            }
 
-                        self.otSession.subscribe(event.stream, remoteViewID, subscriberOptions, self.handleOpenTokError);
+                            var connectionData = JSON.parse(data);
+                            if (connectionData.type === 'CLIENT') {
+                                self.client = false;
+                            }
 
-                        if (connectionData.type === 'CLIENT') {
-                            self.client = true;
+                            // if no other parties in call, hang up
+                            if (!$('[data-stream]:not([data-stream="' + self.selfStreamId + '"])').length) {
+                                console.warn('No other parties in the call!');
+                                self.startTime = 0;
+                                self.started = false;
+                                self.noOneElseInCall = true;
+                            }
                         }
 
-                        if(!self.startTime) {
-                            self.startTime = new Date().getTime();
-                            window.setInterval(function() {
-                                self.time = new Date().getTime() - self.startTime;
-                            }, 1000);
-                            self.started = true;
-                        }
+                        // self connected
+                        self.otSession.on("sessionConnected", function (event) {
+                            self.joinMeetingAsPro(self.selfUserType);
+                        });
 
-                        self.activateParty(event.stream.id);
+                        // self disconnected
+                        self.otSession.on('sessionDisconnected', function sessionDisconnected(event) {
+                            console.log('You were disconnected from the session.', event.reason);
 
-                        self.noOneElseInCall = false;
-                    });
+                            // turn pro video off
+                            $.post('/api/clientVideoVisit/turnProVideoOff', {}, function (_data) {
+                                console.log(_data);
 
-                    // peer disconnected
-                    self.otSession.on("streamDestroyed", function(event) {
-                        onPeerDisconnection(event, event.stream.connection.data);
-                    });
-                    // self.otSession.on("connectionDestroyed", function(event) {
-                    //     debugger;
-                    //     console.log('connectionDestroyed from ' + event.connection.data);
-                    //     onPeerDisconnection(event, event.connection.data);
-                    // });
-
-                    self.otSession.on("connectionCreated", function(event) {
-                        console.log('connectionCreated');
-                        console.log(event);
-                    });
+                                // stop heart beat
+                                if (self.heartbeatTimer) {
+                                    window.clearInterval(self.heartbeatTimer);
+                                    self.heartbeatTimer = false;
+                                }
+                            });
+                        });
+
+                        // initialize the publisher
+                        var publisherOptions = {
+                            // videoSource: canvas.captureStream(1).getVideoTracks()[0], // TODO: Comment this line to use webcam
+                            insertMode: 'append',
+                            width: '100%',
+                            height: '100%',
+                        };
+                        var publisher = OT.initPublisher('self-view', publisherOptions, self.handleOpenTokError);
 
-                    function onPeerDisconnection(event, data) {
+                        publisher.on('streamCreated', function (event) {
+                            var selfView = $('#self-view');
+                            selfView.attr('data-stream', event.stream.id);
+                            selfView.attr('data-connection-data', event.stream.connection.data);
+                            self.selfStreamId = event.stream.id;
+                        });
 
-                        if(event.stream && $('.full-view[data-stream="' + event.stream.id + '"]').length) {
+                        publisher.on('streamCreated', function (event) {
+                            console.log('publisher->streamCreated');
+                            var selfView = $('#self-view');
+                            selfView.attr('data-stream', event.stream.id);
+                            selfView.attr('data-connection-data', event.stream.connection.data);
+                            selfView.attr('data-type', 'PRO');
+                            self.activateParty('self');
+                            $('#self-view').show();
+
+                            // turn pro video on
+                            $.post('/api/clientVideoVisit/turnProVideoOn', {}, function (_data) {
+                                console.log(_data);
+
+                                // start heart beat
+                                self.heartbeatTimer = window.setInterval(function () {
+                                    $.post('/api/clientVideoVisit/registerProMeetingHeartbeat', {}, function (_data) {
+                                        console.log(_data);
+                                    });
+                                }, 5000);
+                            });
+                        });
+
+                        publisher.on('streamDestroyed', function (event) {
+                            event.preventDefault();
+                            console.log('publisher->streamDestroyed');
+                            $('#self-view').hide();
                             var allThumbs = $('.thumbs [data-stream]:not([data-stream=""]):not(.disconnected-view):visible');
-                            if(allThumbs.length) {
-                                $('.thumbs [data-stream]:not([data-stream=""])').each(function() {
-                                    if($(this).attr('data-stream') !== event.stream.id) {
+                            if (allThumbs.length) {
+                                $('.thumbs [data-stream]:not([data-stream=""])').each(function () {
+                                    if ($(this).attr('data-stream') !== $('#self-view').attr('data-stream')) {
                                         self.activateParty($(this).attr('data-stream'));
                                         return false;
                                     }
                                 });
+                            } else {
+                                self.hangUp();
                             }
-                            else {
-                                self.noOneElseInCall = true;
-                            }
-                        }
-
-                        if(event.stream) {
-                            var remoteViewElem = $('[data-stream="' + event.stream.id + '"]');
-                            remoteViewElem.remove();
-                            // if(remoteViewElem.length) {
-                            //     remoteViewElem.attr('data-stream', '');
-                            //     remoteViewElem.attr('data-connection-data', '');
-                            //     remoteViewElem.attr('data-type', '');
-                            //     remoteViewElem.attr('data-name', '');
-                            // }
-                            // remoteViewElem.addClass('disconnected-view')
-                        }
 
-                        var connectionData = JSON.parse(data);
-                        if(connectionData.type === 'CLIENT') {
-                            self.client = false;
-                        }
+                            // turn pro video off
+                            $.post('/api/clientVideoVisit/turnProVideoOff', {}, function (_data) {
+                                console.log(_data);
 
-                        // if no other parties in call, hang up
-                        if(!$('[data-stream]:not([data-stream="' + self.selfStreamId + '"])').length) {
-                            console.warn('No other parties in the call!');
-                            self.startTime = 0;
-                            self.started = false;
-                            self.noOneElseInCall = true;
-                        }
-                    }
-
-                    // self connected
-                    self.otSession.on("sessionConnected", function(event) {
-                        self.joinMeetingAsPro(self.selfUserType);
-                    });
-
-                    // self disconnected
-                    self.otSession.on('sessionDisconnected', function sessionDisconnected(event) {
-                        console.log('You were disconnected from the session.', event.reason);
+                                // stop heart beat
+                                if (self.heartbeatTimer) {
+                                    window.clearInterval(self.heartbeatTimer);
+                                    self.heartbeatTimer = false;
+                                }
+                            });
+                        });
 
-                        // turn pro video off
-                        $.post('/api/clientVideoVisit/turnProVideoOff', {}, function(_data) {
-                            console.log(_data);
 
-                            // stop heart beat
-                            if(self.heartbeatTimer) {
-                                window.clearInterval(self.heartbeatTimer);
-                                self.heartbeatTimer = false;
+                        // Connect to the session
+                        self.otSession.connect(token, function callback(error) {
+                            if (error) {
+                                self.handleOpenTokError(error);
+                            } else {
+                                // If the connection is successful, publish the publisher to the session
+                                self.otSession.publish(publisher, self.handleOpenTokError);
                             }
                         });
-                    });
+                    },
+                    handleOpenTokError: function (e) {
 
-                    // initialize the publisher
-                    var publisherOptions = {
-                        // videoSource: canvas.captureStream(1).getVideoTracks()[0], // TODO: Comment this line to use webcam
-                        insertMode: 'append',
-                        width: '100%',
-                        height: '100%',
-                    };
-                    var publisher = OT.initPublisher('self-view', publisherOptions, self.handleOpenTokError);
-
-                    publisher.on('streamCreated', function(event) {
-                        var selfView = $('#self-view');
-                        selfView.attr('data-stream', event.stream.id);
-                        selfView.attr('data-connection-data', event.stream.connection.data);
-                        self.selfStreamId = event.stream.id;
-                    });
+                    },
 
-                    publisher.on('streamCreated', function(event) {
-                        console.log('publisher->streamCreated');
-                        var selfView = $('#self-view');
-                        selfView.attr('data-stream', event.stream.id);
-                        selfView.attr('data-connection-data', event.stream.connection.data);
-                        selfView.attr('data-type', 'PRO');
-                        self.activateParty('self');
-                        $('#self-view').show();
-
-                        // turn pro video on
-                        $.post('/api/clientVideoVisit/turnProVideoOn', {}, function(_data) {
+                    getOpenTokSessionId: function (_done) {
+                        var self = this;
+                        $.get('/pro/get-opentok-session-key/' + self.clientUid, function (_data) {
+                            self.otSessionId = _data.data;
                             console.log(_data);
+                            _done();
+                        }, 'json');
+                    },
+
+                    joinMeetingAsPro: function (_type) {
+                        var self = this;
+                        $.ajax({
+                            type: 'post',
+                            url: '/api/clientVideoVisit/joinVideoVisitAsPro',
+                            headers: {
+                                'sessionKey': '{{ request()->cookie('sessionKey') }}'
+                            },
+                            data: {uid: self.clientUid},
+                            dataType: 'json'
+                        })
+                            .done(function (_data) {
+                                console.log(_data);
 
-                            // start heart beat
-                            self.heartbeatTimer = window.setInterval(function() {
-                                $.post('/api/clientVideoVisit/registerProMeetingHeartbeat', {}, function(_data) {
-                                    console.log(_data);
-                                });
-                            }, 5000);
-                        });
-                    });
+                                // navigate to this patient on LHS
+                                window.top.openInLHS('/patients/view/' + self.clientUid, true, false);
 
-                    publisher.on('streamDestroyed', function(event) {
-                        event.preventDefault();
-                        console.log('publisher->streamDestroyed');
-                        $('#self-view').hide();
-                        var allThumbs = $('.thumbs [data-stream]:not([data-stream=""]):not(.disconnected-view):visible');
-                        if(allThumbs.length) {
-                            $('.thumbs [data-stream]:not([data-stream=""])').each(function() {
-                                if($(this).attr('data-stream') !== $('#self-view').attr('data-stream')) {
-                                    self.activateParty($(this).attr('data-stream'));
-                                    return false;
-                                }
+                            })
+                            .fail(function (_data) {
+                                console.warn(_data);
+                                alert(_data.message);
                             });
+                    },
+
+                    activateParty: function (_stream = 'self') {
+                        var current = $('.full-view');
+                        if (current.attr('data-stream') === _stream) return;
+                        current.removeClass('full-view').addClass('thumb-view');
+                        if (current.attr('data-type') === 'CLIENT') {
+                            current.prependTo('.thumbs');
+                        } else {
+                            current.appendTo('.thumbs');
                         }
-                        else {
-                            self.hangUp();
-                        }
-
-                        // turn pro video off
-                        $.post('/api/clientVideoVisit/turnProVideoOff', {}, function(_data) {
-                            console.log(_data);
-
-                            // stop heart beat
-                            if(self.heartbeatTimer) {
-                                window.clearInterval(self.heartbeatTimer);
-                                self.heartbeatTimer = false;
-                            }
-                        });
-                    });
-
-
-                    // Connect to the session
-                    self.otSession.connect(token, function callback(error) {
-                        if (error) {
-                            self.handleOpenTokError(error);
+                        if (_stream === 'self') {
+                            $('#self-view')
+                                .removeClass('thumb-view')
+                                .removeClass('disconnected-view')
+                                .addClass('full-view')
+                                .prependTo('.main-view');
                         } else {
-                            // If the connection is successful, publish the publisher to the session
-                            self.otSession.publish(publisher, self.handleOpenTokError);
+                            $('div[data-stream="' + _stream + '"]')
+                                .removeClass('thumb-view')
+                                .removeClass('disconnected-view')
+                                .addClass('full-view')
+                                .prependTo('.main-view');
                         }
-                    });
-                },
-                handleOpenTokError: function(e) {
+                    }
 
                 },
+                mounted: function () {
 
-                getOpenTokSessionId: function(_done) {
                     var self = this;
-                    $.get('/pro/get-opentok-session-key/' + self.clientUid, function(_data) {
-                        self.otSessionId = _data.data;
-                        console.log(_data);
-                        _done();
-                    }, 'json');
-                },
 
-                joinMeetingAsPro: function(_type) {
-                    var self = this;
-                    $.ajax({
-                        type: 'post',
-                        url: '/api/clientVideoVisit/joinVideoVisitAsPro',
-                        headers: {
-                            'sessionKey': '{{ request()->cookie('sessionKey') }}'
-                        },
-                        data: {uid: self.clientUid},
-                        dataType: 'json'
-                    })
-                        .done(function (_data) {
-                            console.log(_data);
+                    $(document).on('click', '.thumbs>div[data-stream]', function () {
+                        self.activateParty($(this).attr('data-stream'));
+                        return false;
+                    });
 
-                            // navigate to this patient on LHS
-                            window.top.openInLHS('/patients/view/' + self.clientUid, true, false);
+                    // poll for new patients and alert
+                    window.setInterval(function () {
+                        self.pollForNextPatient();
+                    }, 5000);
 
-                        })
-                        .fail(function (_data) {
-                            console.warn(_data);
-                            alert(_data.message);
-                        });
-                },
+                    window.onbeforeunload = function () {
+                        if (self.started) {
+                            return "A call is in progress";
+                        }
+                    };
 
-                activateParty: function(_stream = 'self') {
-                    var current = $('.full-view');
-                    if(current.attr('data-stream') === _stream) return;
-                    current.removeClass('full-view').addClass('thumb-view');
-                    if(current.attr('data-type') === 'CLIENT') {
-                        current.prependTo('.thumbs');
-                    }
-                    else {
-                        current.appendTo('.thumbs');
-                    }
-                    if(_stream === 'self') {
-                        $('#self-view')
-                            .removeClass('thumb-view')
-                            .removeClass('disconnected-view')
-                            .addClass('full-view')
-                            .prependTo('.main-view');
-                    }
-                    else {
-                        $('div[data-stream="' + _stream + '"]')
-                            .removeClass('thumb-view')
-                            .removeClass('disconnected-view')
-                            .addClass('full-view')
-                            .prependTo('.main-view');
-                    }
+                    @if(isset($client))
+                        self.client = true;
+                    self.clientUid = '{{ $client->uid }}';
+                    self.videoActive = true;
+                    self.startOpenTokSession();
+                    @endif
                 }
-
-            },
-            mounted: function() {
-
-                var self = this;
-
-                $(document).on('click', '.thumbs>div[data-stream]', function() {
-                    self.activateParty($(this).attr('data-stream'));
-                    return false;
-                });
-
-                // poll for new patients and alert
-                window.setInterval(function() {
-                    self.pollForNextPatient();
-                }, 5000);
-
-                window.onbeforeunload = function() {
-                    if(self.started) {
-                        return "A call is in progress";
+            });
+            new Vue({
+                el: '#queueComponent',
+                data: {
+                    items: []
+                },
+                mounted: function() {
+                    let self = this;
+                    this.refresh();
+                    window.setInterval(function() {
+                        self.refresh();
+                    }, 2500);
+                },
+                methods: {
+                    refresh: function() {
+                        let self = this;
+                        $.get('/patients-in-queue', function(_data) {
+                            self.items = _data;
+                        }, 'json');
+                    },
+                    claim: function(_uid) {
+                        $.post('/api/mcpRequest/claim', {clientUid: _uid}, function(_data) {
+                            if(_data && _data.success) {
+                                // open patient in LHS
+                                window.top.openInLHS('/patients/view/' + _uid);
+                                // open patient video in RHS
+                                openInRHS('/pro/meet/' + _uid);
+                            }
+                            else {
+                                if (_data.message) {
+                                    toastr.error(_data.message);
+                                } else {
+                                    toastr.error('Unable to claim the patient');
+                                }
+                            }
+                        }, 'json');
                     }
-                };
-
-                @if(isset($client))
-                    self.client = true;
-                self.clientUid = '{{ $client->uid }}';
-                self.videoActive = true;
-                self.startOpenTokSession();
-                @endif
-            }
-        });
+                }
+            })
+        })();
     </script>
 
 </body>

+ 1 - 0
routes/web.php

@@ -134,6 +134,7 @@ Route::middleware('pro.auth')->group(function () {
     // pro meeting
     Route::get('/pro/meet/{uid?}', 'PracticeManagementController@meet');
     Route::get('/pro/get-opentok-session-key/{uid}', 'PracticeManagementController@getOpentokSessionKey');
+    Route::get('/patients-in-queue', 'PracticeManagementController@getPatientsInQueue');
 
     //Notes stuff
     Route::get('/note/{note_uid}', 'NoteController@renderNote')->name('render-note');